Thread (10 messages) 10 messages, 4 authors, 2023-06-20

Re: NFSv4.0 Linux client fails to return delegation

From: Chuck Lever III <hidden>
Date: 2023-06-19 21:32:12

On Jun 19, 2023, at 4:19 PM, Trond Myklebust [off-list ref] wrote:

On Mon, 2023-06-19 at 19:54 +0000, Chuck Lever III wrote:
quoted
quoted
On Jun 19, 2023, at 3:19 PM, Trond Myklebust
[off-list ref] wrote:

Hi Dai,

On Mon, 2023-06-19 at 10:02 -0700, dai.ngo@oracle.com wrote:
quoted
Hi Trond,

I'm testing the NFS server with write delegation support and the
Linux client
using NFSv4.0 and run into a situation that needs your advise.

In this scenario, the NFS server grants the write delegation to
the
client.
Later when the client returns delegation it sends the compound
PUTFH,
GETATTR
and DELERETURN.

When the NFS server services the GETATTR, it detects that there
is a
write
delegation on this file but it can not detect that this GETATTR
request was
sent from the same client that owns the write delegation (due to
the
nature
of NFSv4.0 compound). As the result, the server sends CB_RECALL
to
recall
the delegation and replies NFS4ERR_DELAY to the GETATTR request.

When the client receives the NFS4ERR_DELAY it retries with the
same
compound
PUTFH, GETATTR, DELERETURN and server again replies the
NFS4ERR_DELAY. This
process repeats until the recall times out and the delegation is
revoked by
the server.

I noticed that the current order of GETATTR and DELEGRETURN was
done
by
commit e144cbcc251f. Then later on, commit 8ac2b42238f5 was added
to
drop
the GETATTR if the request was rejected with EACCES.

Do you have any advise on where, on server or client, this issue
should
be addressed?
This wants to be addressed in the server. The client has a very
good
reason for wanting to retrieve the attributes before returning the
delegation here: it needs to update the change attribute while it
is
still holding the delegation in order to ensure close-to-open cache
consistency.

Since you do have a stateid in the DELEGRETURN, it should be
possible
to determine that this is indeed the client that holds the
delegation.
I think it needs to be made clear in a specification that this is
the intended and conventional server implementation needed for such
a COMPOUND.

RFC 7530 Section 14.2 says:
quoted
The server will process the COMPOUND procedure by evaluating each
of
the operations within the COMPOUND procedure in order.
2nd paragraph of RFC 7530 Section 15.2.4 says:
quoted
   The COMPOUND procedure is used to combine individual operations
into
a single RPC request. The server interprets each of the operations
in turn. If an operation is executed by the server and the status
of
that operation is NFS4_OK, then the next operation in the COMPOUND
procedure is executed. The server continues this process until
there
are no more operations to be executed or one of the operations has
a
status value other than NFS4_OK.
Obviously in this case the client has sent a well-formed COMPOUND,
but it's not one the server can execute given the ordering
constraint spelled out above.

Can you refer us to a part of any RFC that says it's appropriate
to look ahead at subsequent operations in an NFSv4.0 COMPOUND to
obtain a state or client ID? Otherwise the Linux client will have
the same problem with any server implementation that handles
GETATTR conflicts as described in RFC 7530 Section 16.7.5.

Based on this language I don't believe NFSv4.0 clients can rely on
server implementations to look ahead for client ID information. In
my view the client ought to provide a client ID by placing a RENEW
before the GETATTR. Even in that case, the server implementation
might not be aware that it needs to save the client ID from the
RENEW operation.
No. I don't give a rats arse what the spec says.
The spec is what we've got. If there's a problem with it
somebody should document it. I'm citing spec here because
other server implementations might be in the same boat as
NFSD.

I'm telling you why the client is doing what it does.
Yes, we understand why it's doing that. We read the patch
description for e144cbcc251f. We agree that close-to-open
is a desirable thing.

But I'm not seeing how the updated change attribute or size
is helpful in the write delegation case: a write delegation
is supposed to prevent changes to the file that the client
is not aware of. Can you elaborate why a client that holds
a write delegation would ask for the file size when returning
that delegation?

You either deal
with it, or you don't, but we're not changing the client after 20 years
of this behaviour.
More like 10 years. e144cbcc251f showed up in 2012.

Neither Solaris nor NetApp return a delegation in this case.
They simply don't bother, there's no looking ahead or any
other such behavior. We've already round-tripped with the
nfsv4 working group, that behavior is not compliant with
RFC 7530 Section 16.7.5.

That's why this has worked "for 20 years". Linux depends
on non-compliant or undocumented server behavior for this
trick to work.

If CB_GETATTR avoids this conundrum, then we can re-prioritize
implementation of CB_GETATTR for NFSD.

Seems like CB_GETATTR would have a similar loop, though:
the conflicting GETATTR would trigger a CB_GETATTR and the
server would then return what the client already has.


--
Chuck Lever

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help