sapling/eden/fs/nfs
Katie Mancini 8f3f873874 fix invalidation on NFS
Summary:
TL;DR: File invalidation after checkout is broken on NFS macOS. This proposes a
fix.

Previously, to invalidate things on NFS we opened and closed all the parent
directories of any files/directories that changed during a checkout operation.

This worked on Linux because all open calls result in some request into the
EdenFS daemon (usually a getattr I think). The returned response from this
would show that the directory had update timestamps. So the open would see the
parent directories in their updated state. This would trigger the NFS client to
clear it's caches for that directory and their recursive children to preserve
CTO. CTO or close-to-open consistency guarantees that if on process observed a
file in state A and closed the file, then another process opened that same file
, it will see the file in state A or a later state.

macOS does not seem to do CTO.

It seems that most of the "read" filesystem calls can basically be served from
cache on NFS. Only writes seem to be guaranteed to make it into eden.

So instead of using a "read" filesystem call to trigger invalidation, we need to
use a write one.

I tried opening things in write mode, but the problem is that we need to
invalidate directories (to ensure the entry information is updated) and
directories can not be opened in write mode.

I tried writing 0 bytes to the files themselves that have changed, but this
empty write is short circuited somewhere in the kernel.

The only filesystem call that can be a noop, and seems to trigger a call into
eden is chmod. We are not really working off any guarantees any more, but
it seems to work on both Linux and macOS in my testing so far and is better
than our current broken state of invalidation.

So now to invalidate we chmod parent directories that have changed with their
current mode. Note that this could get extra tricky if we were mixing updating
directory permissions with invalidating them. We would need to ensure we chmod
with the most up to date mode bits. However, because we do not update
permissions anywhere that we also invalidate (checkout does not know how to
update directory permissions) things are a little simpler.

It's important that the chmod can not complete until it seems an updated view of
the parent directory. So we have to be careful about locking here. (Although
that hasn't really changed since we switched from open to chmod.)

One thing that does change is that since chmod is technically a write, it could
cause extra materialization that would be bad for checkout and status
performance. To prevent these problems I have updated setattr to not materialize
a directory when the attribute change is a noop which it should be in our
invalidation technique unless another client modified the directory in the
meantime in which case the directory should be modified anyways. This would
mean that we could end up wiping out clients changes to permissions in the
working copy during checkout. but this matches non eden checkout behavior. So I
think this is ok.

Reviewed By: xavierd

Differential Revision: D35435764

fbshipit-source-id: 196c4995b130b595f9582204237e726e5212993f
2022-04-19 20:32:54 -07:00
..
portmap fs: fix license header 2022-01-04 15:00:07 -08:00
rpc log extra connections to NFS server 2022-04-07 15:34:08 -07:00
test add unit test for access 2022-04-18 21:55:15 -07:00
testharness fs: fix license header 2022-01-04 15:00:07 -08:00
xdr fs: fix license header 2022-01-04 15:00:07 -08:00
CMakeLists.txt add unit test for access 2022-04-18 21:55:15 -07:00
DirList.cpp fs: fix license header 2022-01-04 15:00:07 -08:00
DirList.h fs: fix license header 2022-01-04 15:00:07 -08:00
Mountd.cpp make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
Mountd.h make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
MountdRpc.cpp fs: fix license header 2022-01-04 15:00:07 -08:00
MountdRpc.h fs: fix license header 2022-01-04 15:00:07 -08:00
Nfsd3.cpp fix invalidation on NFS 2022-04-19 20:32:54 -07:00
Nfsd3.h fix invalidation on NFS 2022-04-19 20:32:54 -07:00
NfsDispatcher.cpp fs: fix license header 2022-01-04 15:00:07 -08:00
NfsDispatcher.h fs: fix license header 2022-01-04 15:00:07 -08:00
NfsdRpc.cpp make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
NfsdRpc.h make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
NfsRequestContext.cpp fs: fix license header 2022-01-04 15:00:07 -08:00
NfsRequestContext.h fs: fix license header 2022-01-04 15:00:07 -08:00
NfsServer.cpp make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
NfsServer.h make parsing errors non fatal and log them 2022-03-24 15:20:43 -07:00
NfsUtils.cpp add unit test for access 2022-04-18 21:55:15 -07:00
NfsUtils.h add unit test for access 2022-04-18 21:55:15 -07:00