Tech-invite3GPPspaceIETFspace
959493929190898887868584838281807978777675747372717069686766656463626160595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100
in Index   Prev   Next

RFC 3530

Network File System (NFS) version 4 Protocol

Pages: 275
Obsoletes:  3010
Obsoleted by:  7530
Part 7 of 8 – Pages 180 to 225
First   Prev   Next

ToP   noToC   RFC3530 - Page 180   prevText

14.2.18. Operation 20: OPEN_CONFIRM - Confirm Open

SYNOPSIS (cfh), seqid, stateid-> stateid ARGUMENT struct OPEN_CONFIRM4args { /* CURRENT_FH: opened file */ stateid4 open_stateid; seqid4 seqid; }; RESULT struct OPEN_CONFIRM4resok { stateid4 open_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 open_owner is used by a client. The stateid returned from the OPEN operation is used as the argument for this operation along with the next sequence id for the open_owner. The sequence id passed to the OPEN_CONFIRM must be 1 (one) greater than the seqid passed to the OPEN operation 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 open_owner4 data structures for a given clientid. The client will periodically either dispose of its open_owner4s or stop using them for indefinite periods of time. The latter situation is why the NFS version 4 protocol does not have an
ToP   noToC   RFC3530 - Page 181
   explicit operation to exit an open_owner4: such an operation is of no
   use in that situation.  Instead, to avoid unbounded memory use, the
   server needs to implement a strategy for disposing of open_owner4s
   that have no current lock, open, or delegation state for any files
   and have not been used recently.  The time period used to determine
   when to dispose of open_owner4s is an implementation choice.  The
   time period should certainly be no less than the lease time plus any
   grace period the server wishes to implement beyond a lease time.  The
   OPEN_CONFIRM operation allows the server to safely dispose of unused
   open_owner4 data structures.

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

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

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

   Second, the client sends another OPEN request with a sequence id that
   is incorrect for the open_owner4 (out of sequence).  In this case,
   the server assumes the second OPEN request is valid and the first one
   is a replay.  The server cancels the OPEN state of the first OPEN
   request, establishes an unconfirmed OPEN state for the second OPEN
   request, and responds to the second OPEN request with an indication
   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
   open_owner4, and it receives an operation on the open_owner4 that has
   a stateid but the operation is not OPEN, or it is OPEN_CONFIRM but
   with the wrong stateid?  Then, even if the seqid is correct, the
ToP   noToC   RFC3530 - Page 182
   server returns NFS4ERR_BAD_STATEID, because the server assumes the
   operation is a replay: if the server has no established OPEN state,
   then there is no way, for example, a LOCK operation could be valid.

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

   ERRORS

      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADHANDLE
      NFS4ERR_BAD_SEQID
      NFS4ERR_BAD_STATEID
      NFS4ERR_BADXDR
      NFS4ERR_EXPIRED
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_ISDIR
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_OLD_STATEID
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID

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 open_stateid; seqid4 seqid; uint32_t share_access; uint32_t share_deny; }; RESULT struct OPEN_DOWNGRADE4resok { stateid4 open_stateid; };
ToP   noToC   RFC3530 - Page 183
     union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
      case NFS4_OK:
             OPEN_DOWNGRADE4resok    resok4;
      default:
             void;
     };

   DESCRIPTION

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

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

   On success, the current filehandle retains its value.

   ERRORS

      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADHANDLE
      NFS4ERR_BAD_SEQID
      NFS4ERR_BAD_STATEID
      NFS4ERR_BADXDR
      NFS4ERR_EXPIRED
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_OLD_STATEID
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID
ToP   noToC   RFC3530 - Page 184

14.2.20. Operation 22: PUTFH - Set Current Filehandle

SYNOPSIS filehandle -> (cfh) ARGUMENT struct PUTFH4args { nfs_fh4 object; }; RESULT struct PUTFH4res { /* CURRENT_FH: */ nfsstat4 status; }; DESCRIPTION Replaces the current filehandle with the filehandle provided as an argument. If the security mechanism used by the requester does not meet the requirements of the filehandle provided to this operation, the server MUST return NFS4ERR_WRONGSEC. IMPLEMENTATION Commonly used as the first operator in an NFS request to set the context for following operations. ERRORS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC
ToP   noToC   RFC3530 - Page 185

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. The public filehandle represents the concepts embodied in [RFC2054], [RFC2055], [RFC2224]. The intent for NFS version 4 is that the public filehandle (represented by the PUTPUBFH operation) be used as a method of providing WebNFS server compatibility with NFS versions 2 and 3. The public filehandle and the root filehandle (represented by the PUTROOTFH operation) should be equivalent. If the public and root filehandles are not equivalent, then the public filehandle MUST be a descendant of the root filehandle. IMPLEMENTATION Used as the first operator in an NFS request to set the context for following operations. With the NFS version 2 and 3 public filehandle, the client is able to specify whether the path name provided in the LOOKUP should be evaluated as either an absolute path relative to the server's root or relative to the public filehandle. [RFC2224] contains further discussion of the functionality. With NFS version 4, that type of specification is not directly available in the LOOKUP operation. The reason for this is because the component separators needed to specify absolute vs. relative are not allowed in NFS version 4. Therefore,
ToP   noToC   RFC3530 - Page 186
   the client is responsible for constructing its request such that the
   use of either PUTROOTFH or PUTPUBFH are used to signify absolute or
   relative evaluation of an NFS URL respectively.

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

   There is a form of security negotiation as described in [RFC2755]
   that uses the public filehandle a method of employing SNEGO.  This
   method is not available with NFS version 4 as filehandles are not
   overloaded with special meaning and therefore do not provide the same
   framework as NFS versions 2 and 3.  Clients should therefore use the
   security negotiation mechanisms described in this RFC.

   ERRORS

      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_WRONGSEC

14.2.22. Operation 24: PUTROOTFH - Set Root Filehandle

SYNOPSIS - -> (cfh) ARGUMENT void; RESULT struct PUTROOTFH4res { /* CURRENT_FH: root fh */ nfsstat4 status; };
ToP   noToC   RFC3530 - Page 187
   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

14.2.23. Operation 25: READ - Read from File

SYNOPSIS (cfh), stateid, offset, count -> 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; };
ToP   noToC   RFC3530 - Page 188
   DESCRIPTION

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

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

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

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

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

   If the current filehandle is not a regular file, an error will be
   returned to the client.  In the case the current filehandle
   represents a directory, NFS4ERR_ISDIR is return; otherwise,
   NFS4ERR_INVAL is returned.

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

   On success, the current filehandle retains its value.
ToP   noToC   RFC3530 - Page 189
   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 is
   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 mandatory file locking is on for the file, and if the region
   corresponding to the data to be read from file is write locked by an
   owner not associated the stateid, the server will return the
   NFS4ERR_LOCKED error.  The client should try to get the appropriate
   read record lock via the LOCK operation before re-attempting the
   READ.  When the READ completes, the client should release the record
   lock via LOCKU.

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADHANDLE
      NFS4ERR_BAD_STATEID
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_EXPIRED
      NFS4ERR_FHEXPIRED
      NFS4ERR_GRACE
      NFS4ERR_IO
      NFS4ERR_INVAL
      NFS4ERR_ISDIR
      NFS4ERR_LEASE_MOVED
      NFS4ERR_LOCKED
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NXIO
      NFS4ERR_OLD_STATEID
      NFS4ERR_OPENMODE
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID
ToP   noToC   RFC3530 - Page 190

14.2.24. Operation 26: READDIR - Read Directory

SYNOPSIS (cfh), cookie, cookieverf, dircount, maxcount, attr_request -> cookieverf { cookie, name, attrs } 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; };
ToP   noToC   RFC3530 - Page 191
   DESCRIPTION

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

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

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

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

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

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

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

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

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

   For some filesystem 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 be
   returned.

   On success, the current filehandle retains its value.

   IMPLEMENTATION

   The server's filesystem 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.
ToP   noToC   RFC3530 - Page 193
   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 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_ACCESS
      NFS4ERR_BADHANDLE
      NFS4ERR_BAD_COOKIE
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOTDIR
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_TOOSMALL

14.2.25. Operation 27: READLINK - Read Symbolic Link

SYNOPSIS (cfh) -> linktext
ToP   noToC   RFC3530 - Page 194
   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.

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_BADHANDLE
      NFS4ERR_DELAY
ToP   noToC   RFC3530 - Page 195
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_ISDIR
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOTSUPP
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE

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 filesystem object, the object may be destroyed.
ToP   noToC   RFC3530 - Page 196
   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
   directory removal and REMOVE for non-directory removal. This allowed
   clients to skip checking the file type when being passed a non-
   directory delete system call (e.g., unlink() in POSIX) to remove a
   directory, as well as the converse (e.g., a rmdir() on a non-
   directory) because they knew the server would check the file type.
   NFS version 4 REMOVE can be used to delete any directory entry
   independent of its file type. The implementor of an NFS version 4
   client's entry points from the unlink() and rmdir() system calls
   should first check the file type against the types the system call is
   allowed to remove before issuing a REMOVE. Alternatively, the
   implementor can produce a COMPOUND call that includes a LOOKUP/VERIFY
   sequence to verify the file type before a REMOVE operation in the
   same COMPOUND call.

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

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

   o  The server SHOULD NOT delete the file's directory entry if the
      file was opened with OPEN4_SHARE_DENY_WRITE or
      OPEN4_SHARE_DENY_BOTH.
ToP   noToC   RFC3530 - Page 197
   o  If the file was not opened with OPEN4_SHARE_DENY_WRITE or
      OPEN4_SHARE_DENY_BOTH, the server SHOULD delete the file's
      directory entry.  However, until last CLOSE of the file, the
      server MAY continue to allow access to the file via its
      filehandle.

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_BADCHAR
      NFS4ERR_BADHANDLE
      NFS4ERR_BADNAME
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_FHEXPIRED
      NFS4ERR_FILE_OPEN
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_MOVED
      NFS4ERR_NAMETOOLONG
      NFS4ERR_NOENT
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOTDIR
      NFS4ERR_NOTEMPTY
      NFS4ERR_RESOURCE
      NFS4ERR_ROFS
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE

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; };
ToP   noToC   RFC3530 - Page 198
   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
   filesystem on the server.  On success, the current filehandle will
   continue to be the target directory.

   If the target directory already contains an entry with the name,
   newname, the source object must be compatible with the target:
   either both are non-directories or both are directories and the
   target must be empty.  If compatible, the existing target is removed
   before the rename occurs (See the IMPLEMENTATION subsection of the
   section "Operation 28: REMOVE - Remove Filesystem Object" for client
   and server actions whenever a target is removed).  If they are not
   compatible or if the target is a directory but not empty, the server
   will return the error, NFS4ERR_EXIST.

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

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

   If the oldname refers to a named attribute and the saved and current
   filehandles refer to different filesystem objects, the server will
   return NFS4ERR_XDEV just as if the saved and current filehandles
   represented directories on different filesystems.
ToP   noToC   RFC3530 - Page 199
   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 filesystem on
   the server" means that the fsid fields in the attributes for the
   directories are the same. If they reside on different filesystems,
   the error, NFS4ERR_XDEV, is returned.

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

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

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

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_BADCHAR
      NFS4ERR_BADHANDLE
      NFS4ERR_BADNAME
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_DQUOT
      NFS4ERR_EXIST
      NFS4ERR_FHEXPIRED
      NFS4ERR_FILE_OPEN
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_MOVED
      NFS4ERR_NAMETOOLONG
      NFS4ERR_NOENT
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOSPC
      NFS4ERR_NOTDIR
      NFS4ERR_NOTEMPTY
      NFS4ERR_RESOURCE
ToP   noToC   RFC3530 - Page 200
      NFS4ERR_ROFS
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_WRONGSEC
      NFS4ERR_XDEV

14.2.28. Operation 30: RENEW - Renew a Lease

SYNOPSIS clientid -> () ARGUMENT struct RENEW4args { clientid4 clientid; }; 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 clientid provided via the SETCLIENTID operation. IMPLEMENTATION When the client holds delegations, it needs to use RENEW to detect when the server has determined that the callback path is down. When the server has made such a determination, only the RENEW operation will renew the lease on delegations. If the server determines the callback path is down, it returns NFS4ERR_CB_PATH_DOWN. Even though it returns NFS4ERR_CB_PATH_DOWN, the server MUST renew the lease on the record locks and share reservations that the client has established on the server. If for some reason the lock and share reservation lease cannot be renewed, then the server MUST return an error other than NFS4ERR_CB_PATH_DOWN, even if the callback path is also down.
ToP   noToC   RFC3530 - Page 201
   The client that issues RENEW MUST choose the principal, RPC security
   flavor, and if applicable, GSS-API mechanism and service via one of
   the following algorithms:

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

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

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

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADXDR
      NFS4ERR_CB_PATH_DOWN
      NFS4ERR_EXPIRED
      NFS4ERR_LEASE_MOVED
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE_CLIENTID

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; };
ToP   noToC   RFC3530 - Page 202
   DESCRIPTION

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

   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
      NFS4ERR_RESOURCE
      NFS4ERR_RESTOREFH
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_WRONGSEC

14.2.30. Operation 32: SAVEFH - Save Current Filehandle

SYNOPSIS (cfh) -> (sfh) ARGUMENT /* CURRENT_FH: */ void;
ToP   noToC   RFC3530 - Page 203
   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

14.2.31. Operation 33: SECINFO - Obtain Available Security

SYNOPSIS (cfh), name -> { secinfo } ARGUMENT struct SECINFO4args { /* CURRENT_FH: directory */ component4 name; }; RESULT enum rpc_gss_svc_t {/* From RFC 2203 */ RPC_GSS_SVC_NONE = 1, RPC_GSS_SVC_INTEGRITY = 2, RPC_GSS_SVC_PRIVACY = 3 };
ToP   noToC   RFC3530 - Page 204
     struct rpcsec_gss_info {
             sec_oid4        oid;
             qop4            qop;
             rpc_gss_svc_t   service;
     };

     union secinfo4 switch (uint32_t flavor) {
      case RPCSEC_GSS:
              rpcsec_gss_info        flavor_info;
      default:
              void;
     };

     typedef secinfo4 SECINFO4resok<>;

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

   DESCRIPTION

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

   The result will contain an array which represents the security
   mechanisms available, with an order corresponding to server's
   preferences, the most preferred being first in the array. The client
   is free to pick whatever security mechanism it both desires and
   supports, or to pick in the server's preference order the first one
   it supports.  The array entries are represented by the secinfo4
   structure.  The field 'flavor' will contain a value of AUTH_NONE,
   AUTH_SYS (as defined in [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 [RFC2743]), the quality of protection (as defined in
   [RFC2743]) and the service type (as defined in [RFC2203]).  It is
   possible for SECINFO to return multiple entries with flavor equal to
   RPCSEC_GSS with different security triple values.
ToP   noToC   RFC3530 - Page 205
   On success, the current filehandle retains its value.

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

   IMPLEMENTATION

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

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

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

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

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

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

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

   See the section "Security Considerations" for a discussion on the
   recommendations for security flavor used by SECINFO.

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_BADCHAR
      NFS4ERR_BADHANDLE
      NFS4ERR_BADNAME
      NFS4ERR_BADXDR
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_MOVED
      NFS4ERR_NAMETOOLONG
      NFS4ERR_NOENT
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOTDIR
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE

14.2.32. Operation 34: SETATTR - Set Attributes

SYNOPSIS (cfh), stateid, attrmask, attr_vals -> attrsset ARGUMENT struct SETATTR4args { /* CURRENT_FH: target object */ stateid4 stateid; fattr4 obj_attributes; };
ToP   noToC   RFC3530 - Page 207
   RESULT

     struct SETATTR4res {
             nfsstat4        status;
             bitmap4         attrsset;
     };

   DESCRIPTION

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

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

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

   On success, the current filehandle retains its value.

   IMPLEMENTATION

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

   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
ToP   noToC   RFC3530 - Page 208
   the end of the file to be discarded, and a size greater than the
   current size of the file causes logically zeroed data bytes to be
   added to the end of the file.  Servers are free to implement this
   using holes or actual zero data bytes. Clients should not make any
   assumptions regarding a server's implementation of this feature,
   beyond that the bytes returned will be zeroed.  Servers must support
   extending the file size via SETATTR.

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

   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.

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

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

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

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

   A mask of the attributes actually set is returned by SETATTR in all
   cases.  That mask must not include attributes bits not requested to
   be set by the client, and must be equal to the mask of attributes
   requested to be set only if the SETATTR completes without error.
ToP   noToC   RFC3530 - Page 209
   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_ATTRNOTSUPP
      NFS4ERR_BADCHAR
      NFS4ERR_BADHANDLE
      NFS4ERR_BADOWNER
      NFS4ERR_BAD_STATEID
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_DQUOT
      NFS4ERR_EXPIRED
      NFS4ERR_FBIG
      NFS4ERR_FHEXPIRED
      NFS4ERR_GRACE
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_ISDIR
      NFS4ERR_LOCKED
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOSPC
      NFS4ERR_OLD_STATEID
      NFS4ERR_OPENMODE
      NFS4ERR_PERM
      NFS4ERR_RESOURCE
      NFS4ERR_ROFS
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID

14.2.33. Operation 35: SETCLIENTID - Negotiate Clientid

SYNOPSIS client, callback, callback_ident -> clientid, setclientid_confirm ARGUMENT struct SETCLIENTID4args { nfs_client_id4 client; cb_client4 callback; uint32_t callback_ident; };
ToP   noToC   RFC3530 - Page 210
   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 client uses the SETCLIENTID operation to notify the server of its
   intention to use a particular client identifier, callback, and
   callback_ident for subsequent requests that entail creating lock,
   share reservation, and delegation state on the server.  Upon
   successful completion the server will return a shorthand clientid
   which, if confirmed via a separate step, will be used in subsequent
   file locking and file open requests. Confirmation of the clientid
   must be done via the SETCLIENTID_CONFIRM operation to return the
   clientid and setclientid_confirm values, as verifiers, to the server.
   The reason why two verifiers are necessary is that it is possible to
   use SETCLIENTID and SETCLIENTID_CONFIRM to modify the callback and
   callback_ident information but not the shorthand clientid.  In that
   event, the setclientid_confirm value is effectively the only
   verifier.

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

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

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

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

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

   c be the value of the clientid field returned in the
     SETCLIENTID4resok structure.

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

   s be the setclientid_confirm value returned in the
     SETCLIENTID4resok structure.

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

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

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

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

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

      For brevity of discussion, the remaining description of the
      processing assumes that there was a DRC miss, and that where the
      server has previously recorded a confirmed record for client x,
      the aforementioned principal check has successfully passed.
ToP   noToC   RFC3530 - Page 212
   o  The server checks if it has recorded a confirmed record for { v,
      x, c, l, s }, where l may or may not equal k. If so, and since the
      id verifier v of the request matches that which is confirmed and
      recorded, the server treats this as a probable callback
      information update and records an unconfirmed { v, x, c, k, t }
      and leaves the confirmed { v, x, c, l, s } in place, such that t
      != s. It does not matter if k equals l or not.  Any pre-existing
      unconfirmed { v, x, c, *, * } is removed.

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

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

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

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

      The server returns { d, t }.

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

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

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

      The server returns { e, r }.

      The server awaits confirmation of { e, k } via
      SETCLIENTID_CONFIRM { e, r }.
ToP   noToC   RFC3530 - Page 213
      The server does NOT remove client (lock/share/delegation) state
      for x.

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

      The server returns { d, t }.

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

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

   ERRORS

      NFS4ERR_BADXDR
      NFS4ERR_CLID_INUSE
      NFS4ERR_INVAL
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT

14.2.34. Operation 36: SETCLIENTID_CONFIRM - Confirm Clientid

SYNOPSIS clientid, verifier -> - ARGUMENT struct SETCLIENTID_CONFIRM4args { clientid4 clientid; verifier4 setclientid_confirm; }; RESULT struct SETCLIENTID_CONFIRM4res { nfsstat4 status; };
ToP   noToC   RFC3530 - Page 214
   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) clientid.  The server responds
   with a simple status of success or failure.

   IMPLEMENTATION

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

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

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

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

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

   When the server gets a SETCLIENTID_CONFIRM { c, s } request, it
   processes it in the following manner.
ToP   noToC   RFC3530 - Page 215
   o  It first looks up the request in the DRC. If there is a hit, it
      returns the result cached in the DRC.  The server does not remove
      any relevant leased client state nor does it modify any recorded
      callback and callback_ident information for client { x } as
      represented by the shorthand value c.

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

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

      The server does not remove any relevant leased client state.

      The server returns NFS4_OK.

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

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

   o  The server has not recorded a confirmed { *, *, c, *, * }, and has
      recorded an unconfirmed { *, x, c, k, s }.  Even if this is a
      retry from client, nonetheless the client's first
      SETCLIENTID_CONFIRM attempt was not received by the server.  Retry
      or not, the server doesn't know, but it processes it as if were a
      first try.  If the principal of the unconfirmed { *, x, c, k, s }
      record mismatches that of the SETCLIENTID_CONFIRM request the
      server returns NFS4ERR_CLID_INUSE without removing any relevant
      leased client state.
ToP   noToC   RFC3530 - Page 216
      Otherwise, the server records a confirmed { *, x, c, k, s }. If
      there is also a confirmed { *, x, d, *, t }, the server MUST
      remove the client x's relevant leased client state, and overwrite
      the callback state with k. The confirmed record { *, x, d, *, t }
      is removed.

      Server returns NFS4_OK.

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

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

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

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

      NFS4ERR_BADXDR
      NFS4ERR_CLID_INUSE
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE_CLIENTID

14.2.35. Operation 37: VERIFY - Verify Same Attributes

SYNOPSIS (cfh), fattr -> - ARGUMENT struct VERIFY4args { /* CURRENT_FH: object */ fattr4 obj_attributes; }; RESULT struct VERIFY4res { nfsstat4 status; }; DESCRIPTION The VERIFY operation is used to verify that attributes have a value assumed by the client before proceeding with following operations in the compound request. If any of the attributes do not match then the error NFS4ERR_NOT_SAME must be returned. The current filehandle retains its value after successful completion of the operation. IMPLEMENTATION One possible use of the VERIFY operation is the following compound sequence. With this the client is attempting to verify that the file being removed will match what the client expects to be removed. This sequence can help prevent the unintended deletion of a file. PUTFH (directory filehandle) LOOKUP (file name) VERIFY (filehandle == fh) PUTFH (directory filehandle) REMOVE (file name)
ToP   noToC   RFC3530 - Page 218
   This sequence does not prevent a second client from removing and
   creating a new file in the middle of this sequence but it does help
   avoid the unintended result.

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

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

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_ATTRNOTSUPP
      NFS4ERR_BADCHAR
      NFS4ERR_BADHANDLE
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_FHEXPIRED
      NFS4ERR_INVAL
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOT_SAME
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE

14.2.36. Operation 38: WRITE - Write to File

SYNOPSIS (cfh), stateid, offset, stable, data -> count, committed, writeverf ARGUMENT enum stable_how4 { UNSTABLE4 = 0, DATA_SYNC4 = 1, FILE_SYNC4 = 2 }; struct WRITE4args { /* CURRENT_FH: file */ stateid4 stateid; offset4 offset;
ToP   noToC   RFC3530 - Page 219
             stable_how4     stable;
             opaque          data<>;
     };

   RESULT

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

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

   DESCRIPTION

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

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

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

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

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

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

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

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

   On success, the current filehandle retains its value.

   IMPLEMENTATION

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

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

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

      1. Repeated power failures.
      2. Hardware failures (of any board, power supply, etc.).
      3. Repeated software crashes, including reboot cycle.

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

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

   A suggested verifier would be to use the time that the server was
   booted or the time the server was last started (if restarting the
   server without a reboot results in lost buffers).
ToP   noToC   RFC3530 - Page 222
   The committed field in the results allows the client to do more
   effective caching.  If the server is committing all WRITE requests to
   stable storage, then it should return with committed set to
   FILE_SYNC4, regardless of the value of the stable field in the
   arguments. A server that uses an NVRAM accelerator may choose to
   implement this policy.  The client can use this to increase the
   effectiveness of the cache by discarding cached data that has already
   been committed on the server.

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

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

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

   ERRORS

      NFS4ERR_ACCESS
      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADHANDLE
      NFS4ERR_BAD_STATEID
      NFS4ERR_BADXDR
      NFS4ERR_DELAY
      NFS4ERR_DQUOT
      NFS4ERR_EXPIRED
ToP   noToC   RFC3530 - Page 223
      NFS4ERR_FBIG
      NFS4ERR_FHEXPIRED
      NFS4ERR_GRACE
      NFS4ERR_INVAL
      NFS4ERR_IO
      NFS4ERR_ISDIR
      NFS4ERR_LEASE_MOVED
      NFS4ERR_LOCKED
      NFS4ERR_MOVED
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NOSPC
      NFS4ERR_NXIO
      NFS4ERR_OLD_STATEID
      NFS4ERR_OPENMODE
      NFS4ERR_RESOURCE
      NFS4ERR_ROFS
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID

14.2.37. Operation 39: RELEASE_LOCKOWNER - Release Lockowner State

SYNOPSIS lockowner -> () ARGUMENT struct RELEASE_LOCKOWNER4args { lock_owner4 lock_owner; }; RESULT struct RELEASE_LOCKOWNER4res { nfsstat4 status; }; DESCRIPTION This operation is used to notify the server that the lock_owner is no longer in use by the client. This allows the server to release cached state related to the specified lock_owner. If file locks, associated with the lock_owner, are held at the server, the error NFS4ERR_LOCKS_HELD will be returned and no further action will be taken.
ToP   noToC   RFC3530 - Page 224
   IMPLEMENTATION

   The client may choose to use this operation to ease the amount of
   server state that is held.  Depending on behavior of applications at
   the client, it may be important for the client to use this operation
   since the server has certain obligations with respect to holding a
   reference to a lock_owner as long as the associated file is open.
   Therefore, if the client knows for certain that the lock_owner will
   no longer be used under the context of the associated open_owner4, it
   should use RELEASE_LOCKOWNER.

   ERRORS

      NFS4ERR_ADMIN_REVOKED
      NFS4ERR_BADXDR
      NFS4ERR_EXPIRED
      NFS4ERR_LEASE_MOVED
      NFS4ERR_LOCKS_HELD
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE_CLIENTID

14.2.38. Operation 10044: ILLEGAL - Illegal operation

SYNOPSIS <null> -> () ARGUMENT void; RESULT struct ILLEGAL4res { nfsstat4 status; }; DESCRIPTION This operation is a placeholder for encoding a result to handle the case of the client sending an operation code within COMPOUND that is not supported. See the COMPOUND procedure description for more details. The status field of ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.
ToP   noToC   RFC3530 - Page 225
   IMPLEMENTATION

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

   ERRORS

   NFS4ERR_OP_ILLEGAL



(page 225 continued on part 8)

Next Section