Subject: [nfsv4] random locking questions

From: Ronald E Bretschneider <[email-masked]>
Date: Mon, 2 Jun 2003 14:48:17 -0700

Hi,
   I am sorry to ask so many questions but we have some controversary here
with various interpretations of some locking issues. It seems that when
ever we have two people read something we come up with at least three
interpretations.  I would appreciate it if you could clear up our vision.

thanks,
Ron

1. I assume that NFS V4 does not preclude reads and writes without a
preceeding open. I.e. a client could issue V4 lookup operation to determine
a file handle and then use it with stateid of 0s or 1s to read or write. Is
it correct to allow this behavior?  Is this valid only to an advisory
locking file?
   1. if we allow V4 read or write without open to a mandatory locking
   file, I assume that we get a share reservation for the duration of the
   read or write request. Is this correct?
   2. Certainly a client cannot issue V4 locks without valid open,  the "
   locker parameter " on the lock operation does not make sense otherwise.
   Is this correct?

2. mandatory vs advisory locking questions:
   1. it seems that the stateids (as an indication of what locks are held)
   are only interesting if V4 reads or writes are issued for a mandatory
   locking file. If access is done to an advisory locking file, a byte
   range access conflict is determined during the lock operation. V4 read
   and write operations to an advisory locking file should not check for
   valid lock ranges being held.  If the server did check, there is no
   error code (not_locked for example) to indicate the error. Is this
   correct?
      1. It seems that for special stateids (either stateid = 0s or 1s),
      read or write access to an advisory locking file would simply perform
      the read operation,  just as any other read. Is this correct? I.e.
      for advisory locking files, there is no byte range lock verification
      on a read or write.
   2. it seems for mandatory locking files, if a read or write with a valid
   stateid does not have the requested byte range locked (either none of
   the range is locked or only part of the range is locked) an implicit
   lock for the duration of the operation should be obtained. I come to
   this conclusion because there is no "not_locked" error code on read or
   write. Is this correct?
      1. If an implicit lock is to be obtained, how should it (the implicit
      lock request) behave when a conflict is detected with an explicitly
      obtained lock? Similarily, how should an implicit lock behave when a
      conflict with another implicit lock is detected?  (i.e. should the
      implicit lock always wait? or do we assume that a lock request might
      take some time to be released and, as this is a read, we should not
      always wait. does a client have some expectation that a read will
      finish faster than a lock request?)
      2. If the a conflict is detected between the implicit lock and
      another lock because part, but not all, of the requested range is
      held by another user, would you read or write to the range that could
      be successfully locked (i.e. only perform a partial read or write)?
      Obviously at least the first byte of the range would have to be
      lockable. Or would you return an error of locked?
   3. Section 8.1.4 contains the following sentence "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."  What does the term manditory record lock mean?  Again, is
   this an indication that stateids are only interesting for mandatory
   locking files?
   4. It seems that for stateid = 0s, read or write to a mandatory locking
   file would generate a temporary lock for the range requested. It seems
   that for read or write to an advisory locking file, no temporary lock
   would be obtained. Is this correct?
   5. If no open was issued and a stateid = 0s is used on a read or a write
   to a mandatory locking file, is a temporary share reservation to be
   obtained?
   6. I assume that you allow a nfs v2/v3 protocol client to access a
   mandatory locking file if he has obtained valid byte range locks. But
   what if he has not obtained file share reservations in a NFS V4
   environment (i.e. the operating environment is supporting access from
   V2, V3, and V4 to the same mandatory locking file), do you obtain an
   implicit tempory file share (deny_none, access = read or write) for the
   duration of the read or write RPC?  or because V2/V3 read/write does not
   define an error of locked, do you ignore this. We thought of returning
   ACCES if byte range locks were not held in this case, but do you handle
   share violations the same way?

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

---

From: David Robinson <[email-masked]>
Date: Mon, 02 Jun 2003 18:25:16 -0500

[IBM sure asks a lot of locking questions...]

> it correct to allow this behavior?  Is this valid only to an advisory

Yes, and Maybe. Bottom line is that a server may reject any use
of all 0's or all 1's stateids for any reason.  But it is expected
that doing I/O via a LOOKUP and READ/WRITE without an OPEN will
generally be allowed. It is up to the server to determine how it
interacts with other locking mechanisms and if it will allow
it in the face of an outstanding lock, be it mandatory or advisory.
The design encourages I/O operations that will not corrupt an
active lock, such as reading a read or write locked file but not
allowing a write to a file with any locks. But again, it is up to
the server to define the behavior.

>    read or write request. Is this correct?

No, there are no "implicit" locks for any operation (this was hinted in
early drafts that just confused things). How the server allows
interaction from a client without an OPEN to one with a current share
resv is server defined.  Some servers may never cause a request to be
denied, other may always. In general, share reservations are orthogonal
to byte range locks, one controls access to OPEN a file, the other
to perform I/O. It is logical that a server that allows I/Os without
an OPEN would simply disregard any existing share reservations, but
it would also be consistent that a server may also any access to
a file OPENed with deny-all. These design decisions may be determined
by the underlying operating system, one that has strict native
enforcement of shares may not be able to allow bypass while an OS
that doesn't have native support (e.g. Unix) may allow it.

>    locker parameter " on the lock operation does not make sense otherwise.

In principle it should be possible to lock a file without performing an
OPEN. The only oddity is that the stateid has no meaning because one
has not been established yet, but the server should know it.  What
makes this really strange is that we normally use OPEN to establish
the nfs_lockowner by the server issuing an OPEN_CONFIRM, but that
won't happen in this case. But OPEN_CONFIRM is designed to recover
from a replay of OPEN, which won't happen in this case. But you
can reply LOCK requests because there is a sequence number.

I am not an implementor, but I can see logic in rejecting a LOCK on
a file that was not OPENed.

>    error code (not_locked for example) to indicate the error. Is this

No, there is value in checking for advisory locks to specifically catch
the case where a READ/WRITE gets reordered around a LOCK operation. The
stateid will allow the server to determine if the operation is from
a client that is participating in locking or not.

>    this conclusion because there is no "not_locked" error code on read or

There are no "implicit" locks in NFSv4 from a protocol definition
perspective.  A server may choose to use its own internal locking
structures to serialize requests to manage its internal data structures,
but that is not visible in the protocol.  An implict lock would
define that an error could be returned that implied a lock was
being held when one was not explicitly created, that cannot happen.

>    would be obtained. Is this correct?

Again, there is no temporary locks.

>    to a mandatory locking file, is a temporary share reservation to be

No.

>    share violations the same way?

Interoperability between V2 or V3 and V4 is undefined, it is up to the
implementor to decide what, if any, interaction occurs.  I expect that
many implementations will have no interaction, similar to how many
CIFS implementations do not interact with NFS.

	-David

---

From: Spencer Shepler <[email-masked]>
Date: Mon, 2 Jun 2003 22:55:07 -0500

> a file that was not OPENed.

Rejecting a LOCK request that does not use a valid open_stateid is
required of the server.  The file does need to be OPEN before a LOCK
is attempted.

> a client that is participating in locking or not.

Reordered or the READ/WRITE request is retransmitted.  It could also
be the case that the client is doing something like read-ahead (even
though it should refrain from this behavior when file locks are being
used) and the READ requests are received after a LOCK/LOCKU request.
I see this as a requirement of the server (stateid checking)
regardless of the type of locking being provided (mandatory or
advisory).  This checking and provision for correctness (appropriate
ordering) was one of the main reasons why stateids were added to the
protocol.  In the scenario I just described, the error
NFS4ERR_OLD_STATEID is an appropriate return.

The following issue is whether the server checks the actual ranges
after verifying that the stateid is current valid.  This is where the
advisory/mandatory issue arises.  Mandatory says the server is
checking ranges/advisory -- no.  Therefore, if the server is checking
ranges, it is providing mandatory file locking and therefore has the
appropriate error to return.

> being held when one was not explicitly created, that cannot happen.

David is correct.  I would also suggest search the RFC for
NFS4ERR_LOCKED and read the surrounding text.  It covers the various
scenarios and places the onus on the client to obtain locks if
NFS4ERR_LOCKED is returned as a result of a mismatch between WRITE
range and held LOCK range.

> CIFS implementations do not interact with NFS.

It should also be noted that NFSv2/v3 do not support mandatory file
locking because there is a lack of information provided on the
READ/WRITE operations that allows them to be associated with the LOCK
requests (yet another reason for stateids in NFSv4).  Therefore, there
is no way that an NFSv2/v3 server can provide generic mandatory file
locking to a NFSv2/v3 client regardless of NFSv4 support at the server.

-- 
Spencer