inodes: call nfsUnmount when unmounting

Summary:
Now that the privhelper has the necessary code to unmount an NFS mount, let's
do it. With this in place, this enables `eden mount` and `eden unmount` for NFS
mounts. Unfortunately, it appears that during unmount, releasing the Nfsd3
object triggers a use-after-free in the rpc code

Reviewed By: kmancini

Differential Revision: D26500109

fbshipit-source-id: a210761f818b28b1eb0044f7314a0e2b9017848c
This commit is contained in:
Xavier Deguillard 2021-02-22 22:38:29 -08:00 committed by Facebook GitHub Bot
parent 9f172f672a
commit 52f2984156

View File

@ -637,9 +637,15 @@ folly::Future<folly::Unit> EdenMount::unmount() {
.ensure([this] { channel_.reset(); });
#else
if (getNfsdChannel() != nullptr) {
XLOG(FATAL) << "Unmount is not yet finished for NFS";
serverState_->getNfsServer()->unregisterMount(getPath());
return folly::makeFuture();
return serverState_->getPrivHelper()
->nfsUnmount(getPath().stringPiece())
// Make sure that the Nfsd3 is destroyed in the EventBase that
// it was created on. This is necessary as the various async
// sockets cannot be used in multiple threads and can only be
// manipulated in the EventBase they are attached to.
.via(serverState_->getNfsServer()->getEventBase())
.thenValue([this](auto&&) { channel_ = std::monostate{}; });
} else {
return serverState_->getPrivHelper()->fuseUnmount(
getPath().stringPiece());
@ -1511,8 +1517,6 @@ void EdenMount::channelInitSuccessful(
} else {
static_assert(std::is_same_v<T, EdenMount::NfsdStopData>);
XLOG(FATAL) << "Unmount is not yet finished for NFS";
inodeMap_->setUnmounted();
std::vector<AbsolutePath> bindMounts;
channelCompletionPromise_.setValue(TakeoverData::MountInfo(