tech-invite   World Map     

3GPP     Specs     Glossaries     Architecture     IMS     UICC       IETF     RFCs     Groups     SIP     ABNFs       Search

RFC 3010

 
 
 

NFS version 4 Protocol

Part 6 of 8, p. 126 to 149
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 126 
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

Top      Up      ToC       Page 127 
      NFS4ERR_STALE
      NFS4ERR_WRONGSEC

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.

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

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

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

  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;

Top      Up      ToC       Page 130 
          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.
    */
   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 */
  };

Top      Up      ToC       Page 131 
  struct open_write_delegation4 {
          stateid4        stateid;        /* Stateid for delegation*/
          bool            recall;         /* Pre-recalled flag for
                                             delegations obtained
                                             by reclaim
                                             (CLAIM_PREVIOUS) */
          nfs_space_limit4 space_limit;   /* Defines condition that
                                             the client must check to
                                             determine whether the
                                             file needs to be flushed
                                             to the server on close.
                                             */
          nfsace4         permissions;    /* Defines users who don't
                                             need an ACCESS call as
                                             part of a delegated
                                             open. */
  };

  union open_delegation4
  switch (open_delegation_type4 delegation_type) {
          case OPEN_DELEGATE_NONE:
                  void;
          case OPEN_DELEGATE_READ:
                  open_read_delegation4 read;
          case OPEN_DELEGATE_WRITE:
                  open_write_delegation4 write;
  };

  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      resok4;
   default:
          void;
  };

Top      Up      ToC       Page 132 
   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
      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,

Top      Up      ToC       Page 133 
      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:

      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.

Top      Up      ToC       Page 134 
      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
      case, only a single CLOSE need be done, even though multiple
      OPEN's were completed.

Top      Up      ToC       Page 135 
   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,

Top      Up      ToC       Page 136 
      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_ISDIR
      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

Top      Up      ToC       Page 137 
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
      NFS4ERR_RESOURCE

Top      Up      ToC       Page 138 
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_WRONGSEC


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.

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

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

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

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

14.2.20.  Operation 22: PUTFH - Set Current Filehandle

   SYNOPSIS

      filehandle -> (cfh)

   ARGUMENT

      struct PUTFH4args {
              nfs4_fh         object; };

   RESULT

      struct PUTFH4res {

Top      Up      ToC       Page 142 
              /* 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

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.

Top      Up      ToC       Page 143 
   IMPLEMENTATION

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

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

Top      Up      ToC       Page 145 
      The stateid value for a READ request represents a value returned
      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

Top      Up      ToC       Page 146 
      NFS4ERR_NOFILEHANDLE
      NFS4ERR_NXIO
      NFS4ERR_OLD_STATEID
      NFS4ERR_RESOURCE
      NFS4ERR_SERVERFAULT
      NFS4ERR_STALE
      NFS4ERR_STALE_STATEID
      NFS4ERR_WRONGSEC

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) {

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

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

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


Next RFC Part