Subject: RE: special stateids (was "LOOKUP vs OPEN in NFSV4")

From: "Noveck, Dave" <[email-masked]>
Date: Tue, 21 Aug 2001 21:39:05 -0700

Mike Kupfer wrote: 
> >>>>> "DN" == Noveck, Dave <[email-masked]> writes:
> 
>     DN> The server is implementing mandatory locking (for all files or
>     DN> for particular files, such as those with some mode bit set).
>     DN> I guess you could say that the fact that it doesn't completely
>     DN> ignore mandatory locking on such IO requests "allows mandatory
>     DN> locking to be implemented" but that just seems an odd way to
>     DN> describe the fact that this form of IO, like others, obeys the
>     DN> constraints of mandatory locking.
> 
> I think the point was to contrast with the Unix advisory locking
> model, where the client first obtains locks that cover the I/O region
> and then does the I/O.

With mandatory locking you typically obtain locks that cover the
I/O region then do the I/O.  You can do the same thing with advisory
locking, but you don't have to, since the fact that someone else has
a conflicting lock does not prevent your IO.

The fact that an IO with an all-zero stateid is subject to the same 
locking checks as other IO's (except that it is anonymous), means
that mandatory locking can be implemented, true.  But what is making
it possible to implement mandatory locking is not the case of 
anonymous (all-zero stateid) IO, but rather the case of normal
(i.e. non-special) stateid's which allow the server to match
IO's with owners of possibly conflicting locks.  And that's what
makes the above statement seem extremely odd, at least to me.

> 
>     DN> As I understand the spec now, if we leave aside special
>     DN> stateid's (and non-V4 clients and local access...), share
>     DN> locks are inherently mandatory while it is up to the server to
>     DN> decide whether byte-range locks have mandatory effect (and the
>     DN> server could do it for some files based on mode bits or
>     DN> whatever).  Is that everybody else's understanding?
> 
> That's my understanding.
> 
>     DN> But providing a way a for one client to ignore another
>     DN> client's mandatory locks isn't advisory locking.  It's
>     DN> something different and kind of scary.
> 
> What would you say then is the difference between the current spec and
> advisory locking?

What's the difference?  What isn't different?

If we exclude the odd case of all-one stateid, then we have a 
concictent picture.  Advisory and mandatory byte-range locking
are both supported and either can be implemented at the server's
option.  So, the difference between between the current spec and
advisory locking is that the current spec includes advisory locking
as one of a number (i.e two) of possible implementations.

If you add in the all-ones stateid, you get something different
yet again, which is not any closer to advisory locking.  You have
a client-chosen option to ignore mandatroy byte-range locks if
they are in effect, but only for reads.  So the difference between
that and advisory locking would be:

      Advisory locking applies to both reads and writes.

      Advisory locking is advisory for all clients, rather than just 
      for those that happen to use a particular special stateid (and
      mandatory for everyone else).

So this mechanism provides an escape from mandatory locking semantics
for particular special reads.  Maybe there is a reason to provide that
mechanism, but implementing advisory locking ain't it.

> 
>     >> So, to answer Dave's question, I think that the current text in
>     >> Section 8.1.4 should be changed.  A READ with an all-1 stateid
>     >> should bypass both record locks and share reservations, and a
>     >> WRITE with an all-1 stateid is equivalent to a WRITE with an
>     >> all-0 stateid.
> 
>     DN> "should bypass" as opposed to "must bypass"!
> 
> Right.
> 
> Though it just occurred to me that extending the special all-1
> stateid to share reservations may not make much of a difference, since
> share reservations are primarily enforced on OPEN, not READ/WRITE, and
> OPEN doesn't take any magic stateids.

That's right, if the client does an OPEN.  If he does, than share
reservation will prevent the OPEN from succeeding and he will never
get to issue the IO with the all-one stateid.  

Section 8.9 says that the client has to do the OPEN, although 
there doesn't seem to be any enforcement mechanism.

So it would seem that if the client obeys that rule, then at 
least as far as share reservations, using all-zero and all-one 
stateid's should have the same effect.

> 
>     DN> Generally, the poeple who complain about Windows locks
>     DN> stopping them from accessing a file are complaining about
>     DN> share reservations rather than record (i.e. byte-range)
>     DN> locks.
> 
> Well, that, combined with my observation above about OPEN, implies
> that the all-1's stateid will be of limited usefulness.

That's what I think.

> 
>     DN> my preference would be to avoid two different
>     DN> ways of doing the same thing.  I would rather allow:
> 
>     DN>     Read with all-0: Normal READ with no locks or opens.
>     DN>     Subject (of course) to mandatory locking.
> 
>     DN>     Write with all-0: Normal WRITE with no locks or opens.
>     DN>     Subject (of course) to mandatory locking.
> 
>     DN>     Read with all-1: Special READ which bypasses locking
>     DN>     checks, and thus an exception to mandatory locking, if the
>     DN>     server supports the exception.
> 
>     DN> And make invalid:
> 
>     DN>     Write with all-1: Invalid since a WRITE which bypasses
>     DN>     locking checks is too horrible to contemplate (for long).
> 
> That's okay with me.
> 
> I'm debating with myself whether to propose any significant changes in
> this area (e.g., removal of the magic stateids, or changing OPEN so
> that servers may ignore deny=read under some circumstances).  But none
> of the changes I've thought of is compellingly superior to the current
> spec, so I'm inclined to leave things pretty much as they are.

Removal of all-zero stateid's would not allow an OPEN, READ sequence
in a COMPOUND, which is important to some people (although not to 
me).

Removing the all-ones stateid would have the benefit of removing 
something of dubious utility that adds a lot of confusion.  I'm
not sure if that counts as compellingly superior, at this point.

> 
> I will suggest that servers be allowed to reject deny=read OPENs if
> the requestor only has read access to the file in the first place.

I think the servers already have pretty broad authority to implement
their own security/access policies.

The case that I've heard complaints about is a user who has read
access opening for read with deny=write.  When the owner of the
file cannot write his file, simply because he allowed someone else
to read it, that can be pretty obnoxious.

> 
> Also, as long as I'm thinking about share reservations, did the WG
> ever discuss the Windows semantics where having a file open keeps the
> file from being renamed or deleted?  My reading of RFC 3010 is that v4
> share reservations do not keep the file from being renamed or
> deleted.  Is that everyone's understanding?

My understanding is that that behavior is not required but is allowed.
I expect that windows-based servers will implement things that way,
but that others will not.

> 
>     DN> I think it would help if we added the following text
>     DN> at the end of the fifth paragraph of section 8.5.2.
> 
>     DN>    READs with a stateid of all-ones, must also return
>     DN>    NFS4ERR_GRACE, even though such READs bypass locking
>     DN>    checks, unless the server can determine that no reclaims of
>     DN>    delegations can possibly occur.
>    
> Fifth paragraph or fourth paragraph?

I was thinking the fifth but maybe the fourth is better.

> 
> I wouldn't bother mentioning the locking bypass here.  I'd just say
> something like
> 
>     Note that a stateid of all-ones does not provide any special
>     exceptions for READ requests.  The server must reject such
>     requests with NFS4ERR_GRACE unless it can determine that no
>     reclaims of conflicting delegations can possibly occur.

That's OK with me.

---

From: Mike Kupfer <[email-masked]>
Date: Thu, 23 Aug 2001 22:41:30 -0700

>>>>> "DN" == Noveck, Dave <[email-masked]> writes:

    DN> The fact that an IO with an all-zero stateid is subject to the
    DN> same locking checks as other IO's (except that it is
    DN> anonymous), means that mandatory locking can be implemented,
    DN> true.  But what is making it possible to implement mandatory
    DN> locking is not the case of anonymous (all-zero stateid) IO,
    DN> but rather the case of normal (i.e. non-special) stateid's
    DN> which allow the server to match IO's with owners of possibly
    DN> conflicting locks.  And that's what makes the above statement
    DN> seem extremely odd, at least to me.

It's certainly true that being able to map I/Os to lock owners is
necessary for mandatory locking.  But IMHO, in the Unix world (at
least the part of it I originally come from), "mandatory locking"
connotes "locking is enforced even for programs that don't play nice",
and "advisory locking" connotes "locking is only enforced for programs
that play nice" (and "play nice" means getting locks that cover your
I/Os).  And I believe that the comments in the RFC about the all-zero
stateid and mandatory locking were written in the context of that way
of thinking.

I'd have no problems with having that section of the RFC rewritten,
but I'm not about to propose alternate text. :-)

    DN> The case that I've heard complaints about is a user who has
    DN> read access opening for read with deny=write.  When the owner
    DN> of the file cannot write his file, simply because he allowed
    DN> someone else to read it, that can be pretty obnoxious.

Of course, the counter-argument is if you're going to let someone read
your file, it seems only fair to let them have a consistent view of
the file, where they don't have to worry about you changing the file
out from under them.  Anyone want to suggest automatic versioning for
a minor rev of the protocol?  (Just kidding.  I think.)

    DN> I think it would help if we added the following text at the
    DN> end of the fifth paragraph of section 8.5.2.
    ...

    >> Fifth paragraph or fourth paragraph?

    DN> I was thinking the fifth but maybe the fourth is better.

Part of why I asked was I wasn't sure whether the text at the top of
page 61 counts as a new paragraph.

mike