Subject: [nfsv4] Proposed spec changes for some locking-related issues

From: "Noveck, Dave" <[email-masked]>
Date: Thu, 14 Dec 2006 09:47:20 -0500

The following are the proposed changes to address a number
of issues for draft-09.  These are:

    116 To address the parallel open issue as Spencer has proposed.
    123 To describe the various special stateids.
     86 To modify the op descriptions and errors of the locking ops to
        reflect sessions.
    143 To fix problems in the description of locker4
    144 To fix problems in the explanations of share reservations (In
        the OPEN description)

Except for a some fixes for typos that I've noticed, this takes care
of my changes that will go into draft-09.  Also, this takes care of
all of my issues marked stage0-req.

Context diffs for the .xml and .x files follow.  The base files for
the comparison are equal to those in effect for draft-08 in most cases
although for dotx.d/head.x, the base includes changes for the 
mode_set_masked attribute.

Index: nfsv41_middle_errors.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_errors.xml,v
retrieving revision 1.13
diff -C4 -r1.13 nfsv41_middle_errors.xml
*** nfsv41_middle_errors.xml	19 Oct 2006 15:46:18 -0000	1.13
--- nfsv41_middle_errors.xml	14 Dec 2006 13:51:45 -0000
***************
*** 94,102 ****
  
        <c>NFS4ERR_BAD_SEQID</c>
        <c>10026</c>
        <c>The sequence number in a locking request is neither the next
!       expected number or the last number processed.</c>
  
        <c>NFS4ERR_BADSESSION</c>
        <c>10052</c>
        <c>TDB</c>
--- 94,103 ----
  
        <c>NFS4ERR_BAD_SEQID</c>
        <c>10026</c>
        <c>The sequence number in a locking request is neither the next
!       expected number or the last number processed.  This error does 
!       not apply to and should never be generated in NFSv4.1.</c>
  
        <c>NFS4ERR_BADSESSION</c>
        <c>10052</c>
        <c>TDB</c>
***************
*** 346,354 ****
  
        <c>NFS4ERR_OLD_STATEID</c>
        <c>10024</c>
        <c>A stateid which designates the locking state for a
!       lockowner-file at an earlier time was used.</c>
  
        <c>NFS4ERR_OPENMODE</c>
        <c>10038</c>
        <c>The client attempted a READ, WRITE, LOCK or SETATTR operation
--- 347,356 ----
  
        <c>NFS4ERR_OLD_STATEID</c>
        <c>10024</c>
        <c>A stateid which designates the locking state for a
!       lockowner-file at an earlier time was used.  This error does 
!       not apply to and should never be generated in NFSv4.1.</c>
  
        <c>NFS4ERR_OPENMODE</c>
        <c>10038</c>
        <c>The client attempted a READ, WRITE, LOCK or SETATTR operation
***************
*** 543,551 ****
      <c>CLOSE</c>
      <c>
        NFS4ERR_ADMIN_REVOKED,
        NFS4ERR_BADHANDLE,
-       NFS4ERR_BAD_SEQID,
        NFS4ERR_BAD_STATEID,
        NFS4ERR_BADXDR,
        NFS4ERR_DELAY,
        NFS4ERR_EXPIRED,
--- 545,552 ----
***************
*** 555,563 ****
        NFS4ERR_LEASE_MOVED,
        NFS4ERR_LOCKS_HELD,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
        NFS4ERR_REP_TOO_BIG,
--- 556,563 ----
***************
*** 679,687 ****
        NFS4ERR_LEASE_MOVED,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
        NFS4ERR_NOTSUPP,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
        NFS4ERR_REP_TOO_BIG,
--- 679,686 ----
***************
*** 901,909 ****
        NFS4ERR_ACCESS,
        NFS4ERR_ADMIN_REVOKED,
        NFS4ERR_BADHANDLE,
        NFS4ERR_BAD_RANGE,
-       NFS4ERR_BAD_SEQID,
        NFS4ERR_BAD_STATEID,
        NFS4ERR_BADXDR,
        NFS4ERR_DEADLOCK,
        NFS4ERR_DELAY,
--- 900,907 ----
***************
*** 918,926 ****
        NFS4ERR_LOCK_RANGE,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
        NFS4ERR_NO_GRACE,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OPENMODE,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_RECLAIM_BAD,
        NFS4ERR_RECLAIM_CONFLICT,
--- 916,923 ----
***************
*** 973,981 ****
        NFS4ERR_ACCESS,
        NFS4ERR_ADMIN_REVOKED,
        NFS4ERR_BADHANDLE,
        NFS4ERR_BAD_RANGE,
-       NFS4ERR_BAD_SEQID,
        NFS4ERR_BAD_STATEID,
        NFS4ERR_BADXDR,
        NFS4ERR_EXPIRED,
        NFS4ERR_FHEXPIRED,
--- 970,977 ----
***************
*** 985,993 ****
        NFS4ERR_LEASE_MOVED,
        NFS4ERR_LOCK_RANGE,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
        NFS4ERR_REP_TOO_BIG,
--- 981,988 ----
***************
*** 1090,1098 ****
        NFS4ERR_BADCHAR,
        NFS4ERR_BADHANDLE,
        NFS4ERR_BADNAME,
        NFS4ERR_BADOWNER,
-       NFS4ERR_BAD_SEQID,
        NFS4ERR_BADXDR,
        NFS4ERR_DELAY,
        NFS4ERR_DQUOT,
        NFS4ERR_EXIST,
--- 1085,1092 ----
***************
*** 1134,1150 ****
      <c>OPEN_DOWNGRADE</c>
      <c>
        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_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
        NFS4ERR_REP_TOO_BIG,
--- 1128,1142 ----
***************
*** 1254,1262 ****
        NFS4ERR_LOCKED,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
        NFS4ERR_NXIO,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_OPENMODE,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
--- 1246,1253 ----
***************
*** 1561,1569 ****
        NFS4ERR_LOCKED,
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
        NFS4ERR_NOSPC,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OPENMODE,
        NFS4ERR_PERM,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
--- 1552,1559 ----
***************
*** 1657,1665 ****
        NFS4ERR_MOVED,
        NFS4ERR_NOFILEHANDLE,
        NFS4ERR_NOSPC,
        NFS4ERR_NXIO,
-       NFS4ERR_OLD_STATEID,
        NFS4ERR_OPENMODE,
        NFS4ERR_OP_NOT_IN_SESSION,
        NFS4ERR_REQ_TOO_BIG,
        NFS4ERR_TOO_MANY_OPS,
--- 1647,1654 ----
Index: nfsv41_middle_filelocking.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_filelocking.xml,v
retrieving revision 1.14
diff -C4 -r1.14 nfsv41_middle_filelocking.xml
*** nfsv41_middle_filelocking.xml	19 Oct 2006 15:46:18 -0000
1.14
--- nfsv41_middle_filelocking.xml	14 Dec 2006 13:51:48 -0000
***************
*** 26,34 ****
      In this model, the server owns the state information.  The client
      requests changes in locks and the server responds with the changes
      made.  Non-client-initiated changes in locking state are
infrequent
      and the client receives prompt notification of them and can adjust
!     his view of the locking state to reflect the server's changes. 
    </t>
    <t>
      To support Win32 share reservations it is necessary to provide
      operations which atomically OPEN
--- 26,34 ----
      In this model, the server owns the state information.  The client
      requests changes in locks and the server responds with the changes
      made.  Non-client-initiated changes in locking state are
infrequent
      and the client receives prompt notification of them and can adjust
!     its view of the locking state to reflect the server's changes. 
    </t>
    <t>
      To support Win32 share reservations it is necessary to provide
      operations which atomically OPEN
***************
*** 57,70 ****
        locking interactions.
      </t>
      <section anchor="client_id" title="Client and Session ID" >
      <t>
!      A client must establish a clientid (see <xref target="Client
Identifiers" />) and then one or more sessionids (see <xref
target="Session" />) before
       performing any operations to open, lock, or delegate a file
object.
       The sessionid services as a shorthand referral to an NFSv4.1
client.
      </t>
      </section>
!     <section title="State-owner and Stateid Definition" >
        <t>
          When opening a file or requesting a byte-range lock, the 
          client must specify an identifier which represents the owner
of
          the requested lock.  This identifier is in the form of a
--- 57,71 ----
        locking interactions.
      </t>
      <section anchor="client_id" title="Client and Session ID" >
      <t>
!      A client must establish a clientid (see <xref target="Client
Identifiers" />) 
!      and then one or more sessionids (see <xref target="Session" />)
before
       performing any operations to open, lock, or delegate a file
object.
       The sessionid services as a shorthand referral to an NFSv4.1
client.
      </t>
      </section>
!     <section anchor="state-owner" title="State-owner Definition" >
        <t>
          When opening a file or requesting a byte-range lock, the 
          client must specify an identifier which represents the owner
of
          the requested lock.  This identifier is in the form of a
***************
*** 88,95 ****
--- 89,98 ----
          open file under which the LOCK operation was done.
Delegations
          and layouts, on the other hand, are not associated with a
          specific owner but are associated the client as a whole.
        </t>
+     </section>
+     <section anchor="stateid" title="Stateid Definition" >
        <t>
          When the server grants a lock of any type (including opens,
          byte-range locks, delegations, and layouts) it responds with a

          unique stateid, that represents a set of locks (often a single
***************
*** 103,236 ****
          The stateid is used as a shorthand reference to a lock or set
          of locks and given a stateid the client can determine the
associated
          state-owner
          or state-owners (in the case of an open-owner/lock-owner pair)
!         and the associated. 
!         Clients, however, must not assume any such mapping and must
not
!         use a stateid returned for a given filehandle and state-owner 
!         in the context of a different filehandle or a different
state-owner.
!       </t>
!       <t>
!         The server is free to form the stateid in any manner that it
chooses
!         as long as it is able to recognize invalid and out-of-date
stateids.
!         Although the protocol XDR definition divides the stateid 
!         into 'seqid' and 'other' fields, for the purposes of minor
version
!         one, this distinction is not important and the server may use
the
!         available space as it chooses, with one exception.
!       </t>
!       <t>
!         The exception is that stateids whose 'other' field is either 
!         all zeros or all ones are reserved and may not be generated by
!         the server.  Clients may use the protocol-defined special
stateid
!         values for their defined purposes, but any use of stateid's in
!         this reserved class that are not specially defined by the
protocol
!         MUST result in an NFS4ERR_BAD_STATED being returned.
!       </t>
!       <t>
!         Clients may not compare stateids associated with different
!         filehandles, so that a server might use stateids with the same
!         bit pattern for all opens with a given open-owner or for all
!         sets of byte-range locks associated with a given
lock-owner/open-owner
!         pair.  However, if it does so, it must recognize and reject
any
!         use of stateid when the current filehandle is such that no
lock
!         for that filehandle by that open owner (or
lock-owner/open-owner
!         pair) exists.  
!       </t>
!       <t>
!         Stateid's must remain valid until either a client reboot or a 
!         sever reboot or until the client returns all of the locks 
!         associated with the stateid by means of an operation such as
!         CLOSE or DELEGRETURN.  If the locks are lost due to revocation
!         the stateid remains usable until the client frees it by using 
!         FREE_STATEID.  Stateid's associated with byte-range locks are
!         an exception.  They remain valid even if a LOCKU free all
!         remaining locks, so long as the open file with which they are
!         associated remains open, unless the client does a FREE_STATEID

!         to caused the stateid to be freed.
!       </t>
!       <t>
!         Because each operation using a stateid occurs as part of a
session,
!         each stateid is implicitly associated with the clientid
assigned
!         to that session.  Use of a stateid in the context of a session

          where the clientid is invalid should result in the error 
          NFS4ERR_STALE_STATEID.  Servers MUST NOT do any validation or
          return other errors in this case, even if they have sufficient

          information available to validate stateids associated with an
          out-of-date client.
        </t>
!       <t>
!         
!         One mechanism that may be used to satisfy the requirement that
the 
!         server recognize invalid and out-of-date stateids is for 
!         the server to divide the stateid into two fields.  This
division 
!         may coincide with the documented division into 'seqid' and
'other' 
!         fields or it
!         may divide the stateid field up in any other ay it chooses.
!         <list style='symbols'>
!           <t>
!             An index into a table of locking-state structures.
!           </t>
!           <t>
!             A generation number which is incremented on each
allocation
!             of a table entry a particular allocation of a stateid.
!           </t>
!         </list>
!       </t>
!       <t>
!         And then store in each table entry,
!         <list style='symbols'>
!            <t>
!              The current generation number.
!            </t>
!            <t>
!              The clientid with which the stateid is associated.
!            </t>
!            <t>
!              The filehandle of the file on which the locks are taken.
!            </t>
!            <t>
!              An indication of the type of stateid (open, byte-range
lock,
!              file delegation, directory delegation, layout).
!            </t>
!         </list>
!       </t>
!       <t>
!         With this information, the following procedure would be used
to
!         validate an incoming stateid and return an appropriate error,
!         when necessary:
!         <list style='symbols'>
!           <t>
!             If the current session is associated with an invalid
clientid,
!             return NFS4ERR_STALE_STATEID.
!           </t>
!           <t>
!             If the table index field is outside the range of the 
!             associated table, return NFS4ERR_BAD_STATEID.
!           </t>
!           <t>
!             If the selected table entry is of a different generation
than
!             that specified in the incoming stateid, return
NFS4ERR_BAD_STATEID.
!           </t>
!           <t>
!             If the selected table entry does not match the current
file
!             handle, return NFS4ERR_BAD_STATEID.
!           </t>
!           <t>
!             If the clientid in the table entry does not match the
clientid 
!             associated with the current session, return
NFS4ERR_BAD_STATEID.
!           </t>
!           <t>
!             If the stateid type is not valid for the context in which
the
!             stateid appears, return NFS4ERR_BAD_STATEID.
!           </t>
!           <t>
!             Otherwise, the stateid is valid and the table entry should
contain
!             any additional information about the associated set of
locks,
!             such as open-owner and lock-owner information, as well as
information
!             on the specific locks, such as open modes and byte ranges.
!           </t>
!         </list>
!       </t>
      </section>
      <section title="Use of the Stateid and Locking" >
        <t>
          All READ, WRITE and SETATTR operations contain a stateid.  For
the
--- 106,334 ----
          The stateid is used as a shorthand reference to a lock or set
          of locks and given a stateid the client can determine the
associated
          state-owner
          or state-owners (in the case of an open-owner/lock-owner pair)
!         and the associated filehandle.  When stateids are used the
current
!         filehandle must be the one associated with that stateid.
!       </t>
!       <t>
!         The server may assign stateid's independently for different
clients
!         and a stateid with the same bit pattern for one client may
designate
!         an entirely different set of locks for a different client.
The
!         stateid is always interpreted with respect to the clientid
associated
!         with the current session.  Stateid's apply to all sessions
associated
!         with the given clientid and the client may use a stateid
obtained from
!         one session on another session associated with the same
clientid.
!       </t>
!       <t>
!         Use of a stateid in the context of a session 
          where the clientid is invalid should result in the error 
          NFS4ERR_STALE_STATEID.  Servers MUST NOT do any validation or
          return other errors in this case, even if they have sufficient

          information available to validate stateids associated with an
          out-of-date client.
        </t>
!       <section anchor="stateid_structure" title="Stateid Structure">
!         <t>
!           Stateid's are divided into two fields, a 96-bit si_which
field 
!           identifying the specific set of locks and a 32-bit si_seqid 
!           sequence value.  
!           Except in the case of special stateids, to be discussed
below, 
!           the purpose of the sequence value within NFSv4.1 is to allow
the
!           server to communicate to the client the order in which 
!           operations that modified locking state associated with a
stateid have 
!           been processed.
!         </t>
!         <t>
!           In the case of stateid's associated with opens, i.e. the
stateid's
!           returned by OPEN (the state for the open, rather than that
for the 
!           delegation), OPEN_DOWNGRADE, or CLOSE, the server MUST
provide an
!           si_seqid value starting at one for the first use of a given
si_which
!           value and incremented by one with each subsequent operation
returning a 
!           stateid.
!         </t>
!         <t>
!           In the case of other sorts of stateid's (i.e. stateid's
associated
!           with byte-range locks and delegations), the server MAY
provide an
!           incrementing sequence value on successive stateid's returned
with
!           same identifying field, or it may return the value zero.  If
it does
!           return a non-zero si_seqid value it MUST start at one and be

!           incremented by one with each subsequent operation returning
a 
!           stateid with same
!           si_which value, just as is done with open state.
!         </t>
!         <t>
!           The client when using a stateid as a parameter to an
operation, must,
!           except in the case of a special stateid, set the sequence
value to 
!           zero.  If the value is non-zero, the server MUST return the 
!           error NFS4ERR_BAD_STATEID.
!         </t>
!       </section>
!       <section anchor="special_stateid" title="Special Stateids">
!         <t>
!           Stateid values whose si_which field is either all zeros or
all
!           ones are reserved.  They may not be assigned by the server
but
!           have special meanings defined by the protocol.  The
particular
!           meaning depends on whether the si_which field is all zeros
or
!           all ones and the specific value of the si_seqid field.
!         </t>
!         <t>
!           The following combinations of si_which and si_seqid are
defined
!           in NFSv4.1:
!           <list style='symbols'>
!             <t>
!               When si_which and si_seqid are both zero, the stateid is
!               treated as a special anonymous stateid, which can be
used
!               in READ, WRITE, and SETATTR requests to indicate the
absence
!               of any open state associated with the request.  When an 
!               anonymous stateid value is used, and an existing open
denies 
!               the form of access requested, then access will be denied
to 
!               the request.
!             </t>
!             <t>
!               When si_which and si_seqid are both all ones, the
stateid is
!               a special read bypass stateid.  When this value is used
in
!               WRITE or SETATTR, it is treated like the anonymous
value.
!               When used in READ, the server MAY grant access, even if 
!               access would normally be denied to READ requests.
!             </t>
!             <t>
!               When si_which is zero and si_seqid is one, the stateid 
!               represents the current stateid, which is whatever value 
!               is the last stateid returned by an operation within
!               the COMPOUND.  In the case of an OPEN, the stateid
returned for
!               the open file, and not the delegation is used.  The
stateid 
!               passed to the operation in place of the special value
has its
!               si_seqid value set to zero.  If there is no operation in
the
!               COMPOUND which has returned a stateid value, the server
MUST
!               return the error NFS4ERR_BAD_STATEID.  
!             </t>
!           </list>
!         </t>
!         <t>
!           If a stateid value is used which has all zero or all ones in
the
!           si_which field, but does not match one of the cases above,
the server
!           MUST return the error NFS4ERR_BAD_STATEID.
!         </t>
!         <t>
!           Special stateids, unlike other stateids are not associated
with
!           individual clientid's or filehandles and can be used with
all valid
!           clientid's and filehandles.  In the case of a special 
!           stateid designating the current current stateid, the current
stateid
!           value substituted for the special stateid is associated with
a
!           particular clientid and filehandle.
!         </t>
!       </section>
!       <section anchor="stateid_lifetime" title="Stateid Lifetime and
Validation">
!         <t>
!           Stateid's must remain valid until either a client reboot or
a 
!           sever reboot or until the client returns all of the locks 
!           associated with the stateid by means of an operation such as
!           CLOSE or DELEGRETURN.  If the locks are lost due to
revocation
!           the stateid remains a valid designation of that revoked
state until the 
!           client frees it by using FREE_STATEID.  Stateid's associated

!           with byte-range locks are an exception.  They remain valid
even 
!           if a LOCKU free all remaining locks, so long as the open
file 
!           with which they are associated remains open, unless the
client 
!           does a FREE_STATEID to cause the stateid to be freed.
!         </t>
!         <t>
!           An si_which value must never be reused for a different
purpose
!           (i.e. different filehandle, owner, or type of locks) within
the
!           context of a single clientid.  A server may retain the
si_which
!           value for the same purpose beyond the point where it may
otherwise 
!           be freed but if it does so, it must maintain si_seqid
continuity
!           with previous values, in all case in which it is required to
return
!           incrementing si_seqid values in general.
!         </t>
!         <t>
!           One mechanism that may be used to satisfy the requirement
that the 
!           server recognize invalid and out-of-date stateids is for 
!           the server to divide the si_which field of the stateid into
two 
!           fields.  
!           <list style='symbols'>
!             <t>
!               An index into a table of locking-state structures.
!             </t>
!             <t>
!               A generation number which is incremented on each
allocation
!               of a table entry for a particular use.
!             </t>
!           </list>
!         </t>
!         <t>
!           And then store in each table entry,
!           <list style='symbols'>
!              <t>
!                The current generation number.
!              </t>
!              <t>
!                The clientid with which the stateid is associated.
!              </t>
!              <t>
!                The filehandle of the file on which the locks are
taken.
!              </t>
!              <t>
!                An indication of the type of stateid (open, byte-range
lock,
!                file delegation, directory delegation, layout).
!              </t>
!              <t>
!                The last si_seqid value returned corresponding to the
current
!                si_which value.
!              </t>
!           </list>
!         </t>
!         <t>
!           With this information, the following procedure would be used
to
!           validate an incoming stateid and return an appropriate
error,
!           when necessary:
!           <list style='symbols'>
!             <t>
!               If the current session is associated with an invalid
clientid,
!               return NFS4ERR_STALE_STATEID.
!             </t>
!             <t>
!               If the si_which field is all zeros or all ones, check
that 
!               the si_which and si_seqid match a defined combination
for
!               a special stateid and that that stateid can be used in
the
!               current context.  If not, then return
NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               If the si_seqid field is not zero, return
NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               Otherwise divide the si_which into a table index and an
!               entry generation.
!             </t>
!             <t>
!               If the table index field is outside the range of the 
!               associated table, return NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               If the selected table entry is of a different generation
than
!               that specified in the incoming stateid, return
NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               If the selected table entry does not match the current
file
!               handle, return NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               If the clientid in the table entry does not match the
clientid 
!               associated with the current session, return
NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               If the stateid type is not valid for the context in
which the
!               stateid appears, return NFS4ERR_BAD_STATEID.
!             </t>
!             <t>
!               Otherwise, the stateid is valid and the table entry
should contain
!               any additional information about the associated set of
locks,
!               such as open-owner and lock-owner information, as well
as information
!               on the specific locks, such as open modes and byte
ranges.
!             </t>
!           </list>
!         </t>
!       </section>
      </section>
      <section title="Use of the Stateid and Locking" >
        <t>
          All READ, WRITE and SETATTR operations contain a stateid.  For
the
***************
*** 246,256 ****
          constitutes a share reservation) the stateid (previously
returned by
          the server) must be used to indicate what locks, including
both record
          locks and share reservations, are held by the state-owner.  If
no state
          is established by the client, either record lock or share
reservation,
!         a special stateid of all bits 0 (including all fields of the
stateid) 
!         is used.  Regardless whether a stateid of all
!         bits 0, or a stateid returned by the server is used, if there
is a
          conflicting share reservation or mandatory record lock held on
the
          file, the server MUST refuse to service the READ or WRITE
operation.
        </t>
        <t>
--- 344,355 ----
          constitutes a share reservation) the stateid (previously
returned by
          the server) must be used to indicate what locks, including
both record
          locks and share reservations, are held by the state-owner.  If
no state
          is established by the client, either record lock or share
reservation,
!         a special stateid for anonymous state (zero as si_which and
si_seqid) 
!         is used.
!         Regardless of whether a stateid for anonymous state
!         or a stateid returned by the server is used, if there is a
          conflicting share reservation or mandatory record lock held on
the
          file, the server MUST refuse to service the READ or WRITE
operation.
        </t>
        <t>
***************
*** 297,306 ****
          server's processing of the READ and WRITE operations that
introduces
          the distinction.
        </t>
        <t>
!         Every stateid other than the special stateid values noted in
this
!         section, whether returned by an OPEN-type operation (i.e.
OPEN,
          OPEN_DOWNGRADE), or by a LOCK-type operation (i.e. LOCK or
LOCKU),
          defines an access mode for the file (i.e. READ, WRITE, or
READ-WRITE)
          as established by the original OPEN which caused the
allocation of
          the open stateid
--- 396,405 ----
          server's processing of the READ and WRITE operations that
introduces
          the distinction.
        </t>
        <t>
!         Every stateid with the exception of special stateid values,
!         whether returned by an OPEN-type operation (i.e. OPEN,
          OPEN_DOWNGRADE), or by a LOCK-type operation (i.e. LOCK or
LOCKU),
          defines an access mode for the file (i.e. READ, WRITE, or
READ-WRITE)
          as established by the original OPEN which caused the
allocation of
          the open stateid
***************
*** 329,343 ****
          since the existence of OPEN for read access guarantees that no
          conflicting share reservation can exist.
        </t>
        <t>
!         A special stateid of all bits 1 (one), including all fields in
the 
          stateid indicates a desire to bypass locking checks.  The
server MAY 
          allow READ operations to bypass
          locking checks at the server, when this special stateid is
used.
          However, WRITE operations with 
          this special stateid value MUST NOT bypass locking checks and
are
!         treated exactly the same as if a stateid of all bits 0 were
used.
        </t>
        <t>
          A lock may not be granted while a READ or WRITE operation
using one of
          the special stateids is being performed and the range of the
lock
--- 428,444 ----
          since the existence of OPEN for read access guarantees that no
          conflicting share reservation can exist.
        </t>
        <t>
!         The read bypass special stateid (all bits of si_which and
si_seqid set
!         to one)
          stateid indicates a desire to bypass locking checks.  The
server MAY 
          allow READ operations to bypass
          locking checks at the server, when this special stateid is
used.
          However, WRITE operations with 
          this special stateid value MUST NOT bypass locking checks and
are
!         treated exactly the same as if a special stateid for anonymous
state
!         were used.
        </t>
        <t>
          A lock may not be granted while a READ or WRITE operation
using one of
          the special stateids is being performed and the range of the
lock
***************
*** 963,971 ****
        can be notified, and the invalidated stateid's can be freed and
        lock revocation acknowledged by using FREE_STATEID.
      </t>
    </section>
!   <section title="Share Reservations" >
      <t>
        A share reservation is a mechanism to control access to a file.
It is
        a separate and independent mechanism from record locking.  When
a
        client opens a file, it issues an OPEN operation to the server
--- 1064,1072 ----
        can be notified, and the invalidated stateid's can be freed and
        lock revocation acknowledged by using FREE_STATEID.
      </t>
    </section>
!   <section anchor="share_reserve" title="Share Reservations" >
      <t>
        A share reservation is a mechanism to control access to a file.
It is
        a separate and independent mechanism from record locking.  When
a
        client opens a file, it issues an OPEN operation to the server
***************
*** 1010,1019 ****
    <section title="OPEN/CLOSE Operations" >
      <t>
        To provide correct share semantics, a client MUST use the OPEN
        operation to obtain the initial filehandle and indicate the
desired
!       access and what if any access to deny.  Even if the client
intends to
!       use a stateid of all 0's or all 1's, it must still obtain the
        filehandle for the regular file with the OPEN operation so the
        appropriate share semantics can be applied.  For clients that do
not
        have a deny mode built into their open programming interfaces,
deny
        equal to NONE should be used.
--- 1111,1121 ----
    <section title="OPEN/CLOSE Operations" >
      <t>
        To provide correct share semantics, a client MUST use the OPEN
        operation to obtain the initial filehandle and indicate the
desired
!       access and what access, if any, to deny.  Even if the client
intends to
!       use a special stateid for anonymous state or read bypass, 
!       it must still obtain the
        filehandle for the regular file with the OPEN operation so the
        appropriate share semantics can be applied.  For clients that do
not
        have a deny mode built into their open programming interfaces,
deny
        equal to NONE should be used.
***************
*** 1035,1045 ****
      <t>
        The LOOKUP operation will return a filehandle without
establishing any
        lock state on the server.  Without a valid stateid, the server
will
        assume the client has the least access.  For example, a file
opened
!       with deny READ/WRITE cannot be accessed using a filehandle
obtained
!       through LOOKUP because it would not have a valid stateid (i.e.
using a
!       stateid of all bits 0 or all bits 1).
  
      </t>
    </section>
    <section title="Open Upgrade and Downgrade" >
--- 1137,1148 ----
      <t>
        The LOOKUP operation will return a filehandle without
establishing any
        lock state on the server.  Without a valid stateid, the server
will
        assume the client has the least access.  For example, a file
opened
!       with deny READ/WRITE using a filehandle obtained
!       through LOOKUP could only be read using the special read bypass
stateid
!       and could not be written at all because it would not have a
valid stateid 
!       and a the special anonymus stateid would not be allowed access.
  
      </t>
    </section>
    <section title="Open Upgrade and Downgrade" >
Index: nfsv41_middle_op_close.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_close.xml,v
retrieving revision 1.3
diff -C4 -r1.3 nfsv41_middle_op_close.xml
*** nfsv41_middle_op_close.xml	21 Sep 2006 14:17:59 -0000	1.3
--- nfsv41_middle_op_close.xml	14 Dec 2006 13:51:48 -0000
***************
*** 22,31 ****
      <t>
        The CLOSE operation releases share reservations for the regular
or
        named attribute file as specified by the current filehandle.
The
        share reservations and other state information released at the
server
!       as a result of this CLOSE is only associated with the supplied
!       stateid.  The sequence id provides for the correct ordering.
State
        associated with other OPENs is not affected.
      </t>
      <t>
        If record locks are held, the client SHOULD release all locks
before
--- 22,31 ----
      <t>
        The CLOSE operation releases share reservations for the regular
or
        named attribute file as specified by the current filehandle.
The
        share reservations and other state information released at the
server
!       as a result of this CLOSE is only that associated with the
supplied
!       stateid.  State
        associated with other OPENs is not affected.
      </t>
      <t>
        If record locks are held, the client SHOULD release all locks
before
***************
*** 34,41 ****
--- 34,45 ----
        record locks held.  The server MUST return failure if any locks
would
        exist after the CLOSE.
      </t>
      <t>
+       The seqid value argument must have the value zero.  If any other
+       value is specified the server MUST return the error
NFS4ERR_INVAL.
+     </t>
+     <t>
        On success, the current filehandle retains its value.
      </t>
  
    </section>
Index: nfsv41_middle_op_lock.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_lock.xml,v
retrieving revision 1.4
diff -C4 -r1.4 nfsv41_middle_op_lock.xml
*** nfsv41_middle_op_lock.xml	21 Sep 2006 14:17:59 -0000	1.4
--- nfsv41_middle_op_lock.xml	14 Dec 2006 13:51:52 -0000
***************
*** 45,52 ****
--- 45,82 ----
        In the case that the lock is denied, the owner, offset, and
length
        of a conflicting lock are returned.
      </t>
      <t>
+       The locker argument specifies the lock_owner that is associated
with
+       the LOCK request.  The locker4 structure is a switched union
that
+       indicates whether the client has already created byte range
locking
+       state associated with the current open file and lock owner.  In
the
+       case in which it has, the argument is just a stateid for the set
of
+       locks associated with that open file and lock owner, together
with
+       a lock_seqid value which must be zero.
+       In the case where no such state has been established, or the
client
+       does not have the stateid available, the argument contains the
+       stateid of the open file with which this lock is to be
associated,
+       together with the lock_owner which which the lock is to be
associated.
+       The open_to_lock_owner case covers the very first lock done by a
+       lock_owner for a given open file and offers a method to use the 
+       established state of the open_stateid to transition to the use
of 
+       a lock stateid.
+     </t>
+     <t>
+       The client field of the lock owner, and all seqid values in
+       the arguments
+       have zero as the only valid value.  When any of these are
specified as
+       other than zero, the server MUST return an
+       NFS4ERR_INVAL.  The clientid with which all owners and stateids 
+       are associated
+       is the clientid associated with the session on which the request

+       was issued.  The clientid appearing in a LOCK4denied structure
+       is the actual client associated with the conflicting lock,
whether
+       this is the clientid associated with the current session, or a 
+       different one.
+     </t>
+     <t>
        On success, the current filehandle retains its value.
      </t>
    </section>
    <section toc="exclude" anchor="OP_LOCK_IMPLEMENTATION"
title="IMPLEMENTATION">
***************
*** 83,101 ****
        the server will return NFS4ERR_LOCK_NOTSUPP.  Such operations
may not
        perfectly reflect the required semantics in the face of
conflicting
        lock requests from other clients.
      </t>
-     <t>
-       The locker argument specifies the lock_owner that is associated
with
-       the LOCK request.  The locker4 structure is a switched union
that
-       indicates whether the lock_owner is known to the server or if
the
-       lock_owner is new to the server.  In the case that the
lock_owner is
-       known to the server and has an established lock_seqid, the
argument is
-       just the lock_owner and lock_seqid.  In the case that the
lock_owner
-       is not known to the server, the argument contains not only the
-       lock_owner and lock_seqid but also the open_stateid and
open_seqid.
-       The new lock_owner case covers the very first lock done by the
-       lock_owner and offers a method to use the established state of
the
-       open_stateid to transition to the use of the lock_owner.
-     </t>
    </section>
  </section>
--- 113,118 ----
Index: nfsv41_middle_op_lockt.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_lockt.xml,v
retrieving revision 1.3
diff -C4 -r1.3 nfsv41_middle_op_lockt.xml
*** nfsv41_middle_op_lockt.xml	21 Sep 2006 14:17:59 -0000	1.3
--- nfsv41_middle_op_lockt.xml	14 Dec 2006 13:51:52 -0000
***************
*** 20,28 ****
    <section toc="exclude" anchor="OP_LOCKT_DESCRIPTION"
title="DESCRIPTION">
      <t>
        The LOCKT operation tests the lock as specified in the
arguments.  If
        a conflicting lock exists, the owner, offset, length, and type
of the
!       conflicting lock are returned; if no lock is held, nothing other
than
        NFS4_OK is returned.  Lock types READ_LT and READW_LT are
processed in
        the same way in that a conflicting lock test is done without
regard to
        blocking or non-blocking.  The same is true for WRITE_LT and
WRITEW_LT.
      </t>
--- 20,32 ----
    <section toc="exclude" anchor="OP_LOCKT_DESCRIPTION"
title="DESCRIPTION">
      <t>
        The LOCKT operation tests the lock as specified in the
arguments.  If
        a conflicting lock exists, the owner, offset, length, and type
of the
!       conflicting lock are returned.  
!       The owner field in the results includes the clientid of the
owner of 
!       conflicting lock, whether this is the clientid associated with
the
!       current session or a different clientid.
!       If no lock is held, nothing other than
        NFS4_OK is returned.  Lock types READ_LT and READW_LT are
processed in
        the same way in that a conflicting lock test is done without
regard to
        blocking or non-blocking.  The same is true for WRITE_LT and
WRITEW_LT.
      </t>
***************
*** 31,38 ****
--- 35,48 ----
        NFS4ERR_BAD_RANGE errors are returned under the same
circumstances
        as for LOCK.
      </t>
      <t>
+       The clientid field of the owner should be specified as zero.
The 
+       clientid used for ownership comparisons is that associated with
the
+       session on which the request is issued.  If the clientid field
is 
+       other than zero, the server MUST return the error NFS4ERR_INVAL.
+     </t>
+     <t>
        On success, the current filehandle retains its value.
      </t>
    </section>
    <section toc="exclude" anchor="OP_LOCKT_IMPLEMENTATION"
title="IMPLEMENTATION">
***************
*** 46,54 ****
      <t>
        LOCKT uses a lock_owner4 rather a stateid4, as is used in
        LOCK to identify the owner.  This is because the client does not

        have to open the file to test for the existence of a lock, so
!       a stateid may not be available.
      </t>
      <t>
        The test for conflicting locks should exclude locks for the
current
        lockowner.  Note that since such locks are not examined the
possible
--- 56,64 ----
      <t>
        LOCKT uses a lock_owner4 rather a stateid4, as is used in
        LOCK to identify the owner.  This is because the client does not

        have to open the file to test for the existence of a lock, so
!       a stateid may not be available.  
      </t>
      <t>
        The test for conflicting locks should exclude locks for the
current
        lockowner.  Note that since such locks are not examined the
possible
Index: nfsv41_middle_op_locku.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_locku.xml,v
retrieving revision 1.3
diff -C4 -r1.3 nfsv41_middle_op_locku.xml
*** nfsv41_middle_op_locku.xml	21 Sep 2006 14:17:59 -0000	1.3
--- nfsv41_middle_op_locku.xml	14 Dec 2006 13:51:52 -0000
***************
*** 29,36 ****
--- 29,40 ----
        NFS4ERR_BAD_RANGE errors are returned under the same
circumstances as
        for LOCK.
      </t>
      <t>
+       The seqid parameter should be specified as zero.  If any other
value
+       is specified, the server must return an NFS4ERR_INVAL error.
+     </t>
+     <t>
        On success, the current filehandle retains its value.
      </t>
    </section>
    <section toc="exclude" anchor="OP_LOCKU_IMPLEMENTATION"
title="IMPLEMENTATION">
Index: nfsv41_middle_op_open.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_open.xml,v
retrieving revision 1.10
diff -C4 -r1.10 nfsv41_middle_op_open.xml
*** nfsv41_middle_op_open.xml	23 Oct 2006 04:16:54 -0000	1.10
--- nfsv41_middle_op_open.xml	14 Dec 2006 13:52:01 -0000
***************
*** 82,94 ****
        arguments.  The client specifies at OPEN the required
share_access and
        share_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_SHARE_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'.
! 	<cref>Add an xref to the Share Reservations section</cref>
      </t>
      <t>
        In the case that the client is recovering state from a server
failure,
        the claim field of the OPEN argument is used to signify that the
--- 82,103 ----
        arguments.  The client specifies at OPEN the required
share_access and
        share_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_SHARE_DENIED.  
!       For each OPEN, 
!       the client must provide a value for the owner
!       field for the OPEN argument.  The clientid associated with the
owner
!       is not derived from the client field of the owner parameter but
is
!       instead the clientid associated with the session on which the
request 
!       is issued.  If the clientid field of the owner parameter is not
zero,
!       the server MUST return an NFS4ERR_INVAL error.
!       For additional discussion of
!       SHARE semantics see <xref target="share_reserve" />.
!     </t>
!     <t>
!       The seqid value is not used in NFSv4.1.  If the value passed is
not
!       zero, the server MUST return an NFS4ERR_INVAL error.
      </t>
      <t>
        In the case that the client is recovering state from a server
failure,
        the claim field of the OPEN argument is used to signify that the
***************
*** 396,406 ****
        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.
! <cref>Isn't this mechanism redundant if the server supports a stable
! session replay cache?</cref>
      </t>
      <t>
        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
--- 405,415 ----
        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.  This mechanism allows reliable exclusive
!       create semantics even when the server does not support the
storing
!       session replay information in stable storage.
      </t>
      <t>
        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
Index: nfsv41_middle_op_open_downgrade.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_open_downgrade.xml,v
retrieving revision 1.3
diff -C4 -r1.3 nfsv41_middle_op_open_downgrade.xml
*** nfsv41_middle_op_open_downgrade.xml	21 Sep 2006 14:17:59 -0000
1.3
--- nfsv41_middle_op_open_downgrade.xml	14 Dec 2006 13:52:06 -0000
***************
*** 36,43 ****
--- 36,47 ----
        subsets of those already granted, it is not possible for this
request
        to be denied because of conflicting share reservations.
      </t>
      <t>
+       The seqid value is not used in NFSv4.1.  If the value passed is
not
+       zero, the sevrer MUST return an NFS4ERR_INVAL error.
+     </t>
+     <t>
        On success, the current filehandle retains its value.
      </t>
    </section>
  </section>
Index: dotx.d/head.x
===================================================================
RCS file: /cvs/stdk/NFSv41/dotx.d/head.x,v
retrieving revision 1.4
diff -C4 -r1.4 head.x
*** dotx.d/head.x	12 Dec 2006 08:19:05 -0000	1.4
--- dotx.d/head.x	14 Dec 2006 13:52:13 -0000
***************
*** 747,756 ****
  /*
   * Stateid
   */
  struct stateid4 {
! 	uint32_t	seqid;
! 	opaque		other[12];
  };
  
  /*
   * NFSv4.0 Long Hand Client ID
--- 747,756 ----
  /*
   * Stateid
   */
  struct stateid4 {
! 	uint32_t	si_seqid;
! 	opaque		si_which[12];
  };
  
  /*
   * NFSv4.0 Long Hand Client ID
Index: dotx.d/lock_args.x
===================================================================
RCS file: /cvs/stdk/NFSv41/dotx.d/lock_args.x,v
retrieving revision 1.1
diff -C4 -r1.1 lock_args.x
*** dotx.d/lock_args.x	16 Sep 2006 19:25:33 -0000	1.1
--- dotx.d/lock_args.x	14 Dec 2006 13:52:13 -0000
***************
*** 1,6 ****
  /*
!  * For LOCK, transition from open_owner to new lock_owner
   */
  struct open_to_lock_owner4 {
  	seqid4		open_seqid;
  	stateid4	open_stateid;
--- 1,7 ----
  /*
!  * For LOCK, transition from open_stateid and lock_owner
!  * to a lock stateid.
   */
  struct open_to_lock_owner4 {
  	seqid4		open_seqid;
  	stateid4	open_stateid;
***************
*** 8,16 ****
  	lock_owner4	lock_owner;
  };
  
  /*
!  * For LOCK, existing lock_owner continues to request file locks
   */
  struct exist_lock_owner4 {
  	stateid4	lock_stateid;
  	seqid4		lock_seqid;
--- 9,18 ----
  	lock_owner4	lock_owner;
  };
  
  /*
!  * For LOCK, existing lock stateid  continues to request new
!  * file lock for the same lock_owner and open_stateid.
   */
  struct exist_lock_owner4 {
  	stateid4	lock_stateid;
  	seqid4		lock_seqid;

_______________________________________________
nfsv4 mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/nfsv4