Subject: RE: downgrade/upgrade (was Re: Spec-related discussions at the Ba ke-off)

From: "Noveck, Dave" <[email-masked]>
Date: Fri, 3 Nov 2000 08:06:44 -0800

> "David Robinson" <[email-masked]> writes:

> > I don't recall what the motivation for an upgrade/downgrade OPEN was.

> Just scanned the archive, looking for "downgrade" in a case insensitive
> search. BTW, I was not a participant in the discussion, so this is all
> based on reading the archive and not recollection of my thoughts at the
> time.

> The deal is this:

> UNIX process opens file "A" with mode READ and
> the nfs v4 file system issues the OPEN with mode READ, and deny NONE.

> The same process now opens "A" again, but this time with mode WRITE.
> NFSv4 has no notion of a unique file descriptor. Given that the
> nfs_lockowner is the same, and the file is the same, the only way the server
> can handle this is to treat the operation as an upgrade. So the nfsv4
> file system sends an OPEN with mode READ/WRITE and deny NONE.

> I gathered from the discussion that the Windows API would not allow the
> same process to open the file with two different modes, but in any
> case, this is immaterial, since UNIX does.

I may have misunderstood him, but I gathered from Carl, that Windows would
allow the same process to open the file with two different modes as long
as those modes are compatible (assuming exactly rules that would apply
for two different processes).

Carl, could you confirm or deny?

      A process can open the file for READ, DENY=READ, and then

      the same process can open the same file for WRITE, DENY=WRITE

> When the process closes one of the file descriptors on "A", the NFSv4
> file system needs to downgrade the SHARE to either READ or WRITE on the
> server. It cannot issue a CLOSE, because this removes all the SHARE
> state, so would leave a window for another client to OPEN the file with
> a DENY=~NONE, and so prevent the client from doing another OPEN to
> re-open the file. So an OPEN_DOWNGRADE operation is needed to deal with
> this.

Also, there may be byte-range locks associated with the first open so
closing could run into a problem there as well.

> > I don't believe that any existing APIs that handle shares has this
> > capability so I question why it shouldn't just be done with a CLOSE
> > followed by an OPEN, if it is ever needed.

> See the above.

---

From: "Noveck, Dave" <[email-masked]>
Date: Mon, 6 Nov 2000 06:13:29 -0800

> > > It might implement this by handling the open upgrade by doing a second
open 
> > > and then closing one of its open's when a
> > > downgrade is done. There are some problems with this. As the spec stands, 
> > > the client is not constrained in precisely
> > > what downgrades it would do, making it possible for it to make requests, 
> > > that cannot be handled by the server closing
> > > one of its opens. Even if this could be resolved, there remains an issue

> I don't understand. The spec is very explicit in that OPEN_DOWNGRADE
> must not add bits not present in the previous OPEN for the nfs_lockowner/file
> pair. 

Here is the worrisome case:

    An OPEN request is done for READ, DENY=READ (NT server does the
    corresponding open).

    an OPEN request (same lockower, same file) is done for WRITE,
    DENY=WRITE (NT server does corresponding second open on the same
    file and upgrades total open state to READ+WRITE,DENY=READ+WRITE

    An OPEN_DOWNGRADE request is done specifying READ, DENY=WRITE,
    which is a subset (so the spec thngs it's OK) but the server 
    can't handle it but closing one of its two open files.   

> > > with byte-range locks. The NT server has no
> > > way of knowing which of his opens to assign the locks to. He might assign 
> > > them to an open which needs to be closed
> > > to satisfy a subsequent downgrade. 

> For a given nfs_lockowner/file_handle pair there is just one
> oustanding OPEN. Thus the byte range locks would be moved to the second open,
> which then becomes the only open after the previous open is closed.

The issue there is that there is no way for the NT server to atomically
move locks between open files.  You can release a lock and then do the
lock under the other open file but someone else (another local process)
could get the lock you released.

---

From: "Noveck, Dave" <[email-masked]>
Date: Tue, 7 Nov 2000 12:30:30 -0800

> > > As the Unix process that opens the file a second time creates a second
> > > file descriptor, it can be argued that this is a different open and the
> > client should not collapse them into a single access.
> > 
> > It could be so argued, if someone was prepared to do it.
> > 
> > Are you saying that the spec should be modified so that clients are
> > required to do that?

> I have not spent the time to really understand how Windows works on
> this,
> but it appears that there can be a compromise that works in most
> interesting
> cases.  Since Unix doesn't really have a SHARE interface, the
> interpretation
> of what it should generate can be adapted as needed. On the Windows
> side,
> it has real APIs that expect certain behavior so the protocol should
> bend towards it within reason. So I would look to defining the server
> semantics strictly and putting the burden more on the client in this
> case.
> So I would argue that the burden is on the Unix side to find an
> acceptable
> method to accomedate Windows servers.

OK, but I'm inclined to think that asking clients to essentially 
overload the notion of lockowner is not the way to do it.  Right 
now everybody knows (sort of) what a lockowner is and it would be
nice to keep it that way.

This helps if there is additional goal to not change the .x file,
but this problem is hard enough to do without that additional
constraint.  Adding that restriction really makes my head hurt.  

> > > To solve this
> > > problem a client can create a new nfs_owner even though both OPENs are
> > > within the same process.
> > 
> > It is the server which has the problem dealing with this.
> > 
> > The client is not going to create new lock_owners unless the spec tells
> > him that (and when) he must.

> I realize that it is the servers problem, I am saying we should consider
> disallowing the client from doing that or at least forcing them to
> handle the server saying, "sorry, unable".

I don't understand this statement.  What is the referant for "that" in
"disallowing the client from doing that"?

> > > This will cause some extra work as many Unix
> > > OSes may merge the record locking state of all descriptors to the same
> > > file within the same process. But for other accesses this should not
> > > create any problems having the same process with multiple owners.
> > 
> > I believe there are situations in which this would not work, at least
> > if work is defined as having a UNIX client and server work together and
> > get the same results as wuld be gotten with a local file system.  There
> > are lots of cases in which the flock behavior (and mandatory locking as
> > well depends) on making a distinction based on whether the owner of
> > the existing lock and the process dong an operation are "the same".
> > If the client defines two owners within the same process (eseentially
> > willy-nilly), this isn't going to work right.

This is where this really gets difficult.  UNIX doesn't have SHARE
semantics but it does have flock semantics.  

> > 
> > Besides, this has the same problems as changing stateid to be per-open-
> > file-instance.  How is the client implementation to know for which
> > open file (and thus for which lockowner) a given lock operation is
> > for, if this information is not available across the VOP interface,
> > and I think it isn't in many UNIX'es?

> True, under most VFS interfaces there is little distinction between a
> file
> opened once or N times.

:-(