sapling/eden/fs/takeover
Xavier Deguillard e50725d2cb inodes: rename FUSE refcount to fs refcount
Summary:
One of the issue that EdenFS on Windows is currently facing is around
invalidation during an update. In effect, EdenFS is over invalidating, which
causes update to be slower than it should be, as well as EdenFS recursively
triggering ProjectedFS callbacks during invalidation. Both of these are a
sub-par UX.

The reason this issue exist is multi-faceted. First, the update code follows
the "kPreciseInodeNumberMemory" path which enforces that a directory that is
present in the overlay needs to be invalidated, even if it isn't materialized.
The second reason is that no reclamation is done for the overlay, combine the
two and you get an update that gets both slower over time and will issue
significantly more invalidation that is needed.

Solving this is a bit involved. We could for instance start by reclaiming
inodes from the overlay, but this wouldn't be effective as we use the fact that
an inode is present in the overlay as a way to know that the file is cached in
the overlay. If we reclaim from the overlay we simply won't be invalidating
enough and some files will be out of date.

It turns out that we already have a mechanism to track what is cached by the
kernel: the fuse refcount. On Linux/macOS, everytime an inode is returned to
the kernel, this refcount incremented, and the kernel then notifies us when it
forgot about it, at which point the refcount can be decremented. On Windows,
the rules are a bit different, and a simple flag is sufficient: set when we
write a placeholder on disk (either during a directory listing, or when
ProjectedFS asks for it), and unset at invalidation time during update. There
is however a small snag in this plan. On Linux, the refcount starts at 0 when
EdenFS starts as a mount/unmount will clear all the kernel references on the
inodes. On Windows, the placeholder aren't disappearing when EdenFS dies or is
stopped, so we need a way to scan the working copy when EdenFS starts to know
which inodes should be loaded (an UnloadedInode really).

The astute reader will have noticed that this last part is effectively a
O(materialized) operation that needs to happen at startup, which would be
fairly expensive in itself. It turns out that we really don't have choice and
we need to do it regardless due to Windows not disallowing writes to the
working copy when EdenFS is stopped, and thus for EdenFS to be aware of the
actual state of the working copy, it needs to scan it at startup...

The first step in doing all of this is to simply rename the various places that
uses "fuse refcount" to "fs refcount" which is what this diff does.

Reviewed By: chadaustin

Differential Revision: D24716801

fbshipit-source-id: e9e6ccff14c454e9f2626fab23daeb3930554b1a
2020-11-04 17:34:01 -08:00
..
test Replace Future<T>::getTry with Future<T>::result 2020-07-14 11:04:12 -07:00
CMakeLists.txt build: compile takeover/ on Windows 2020-09-16 12:31:46 -07:00
takeover.thrift inodes: rename FUSE refcount to fs refcount 2020-11-04 17:34:01 -08:00
TakeoverClient.cpp fs: ifdef linux/macos only files 2020-09-23 12:20:41 -07:00
TakeoverClient.h add EdenServer recovery step and recover after failed takeover data send handshake 2020-04-07 09:52:21 -07:00
TakeoverData.cpp fs: ifdef linux/macos only files 2020-09-23 12:20:41 -07:00
TakeoverData.h utils: move win/utils/Stub.h to utils/NotImplemented.h 2020-09-16 12:31:46 -07:00
TakeoverHandler.h add EdenServer recovery step and recover after failed takeover data send handshake 2020-04-07 09:52:21 -07:00
TakeoverServer.cpp fs: ifdef linux/macos only files 2020-09-23 12:20:41 -07:00
TakeoverServer.h add fault injection to TakeoverServer 2020-04-07 09:52:21 -07:00