win: pass the PrjfsChannel to ProjectedFS callbacks

Summary: A following diff will make use of the channel.

Reviewed By: wez

Differential Revision: D23505510

fbshipit-source-id: c044fff51c8771b1ead86333317e5c617184075c
This commit is contained in:
Xavier Deguillard 2020-09-11 08:35:51 -07:00 committed by Facebook GitHub Bot
parent 54d43b7f95
commit e9da08d4d3
5 changed files with 66 additions and 56 deletions

View File

@ -1205,19 +1205,24 @@ folly::Future<TakeoverData::MountInfo> EdenMount::getChannelCompletionFuture() {
folly::Future<EdenMount::channelType> EdenMount::channelMount(bool readOnly) {
return folly::makeFutureWith([&] { return &beginMount(); })
.thenValue([this, readOnly](folly::Promise<folly::Unit>* mountPromise) {
AbsolutePath mountPath = getPath();
#ifdef _WIN32
return folly::makeFutureWith(
[readOnly, this]() -> folly::Future<FsChannel*> {
auto channel = new PrjfsChannel(this);
[this,
mountPath = std::move(mountPath),
readOnly]() -> folly::Future<FsChannel*> {
auto channel = new PrjfsChannel(
mountPath,
getDispatcher(),
serverState_->getProcessNameCache());
channel->start(
readOnly,
getDispatcher(),
serverState_->getReloadableConfig()
.getEdenConfig()
->prjfsUseNegativePathCaching.getValue());
return channel;
})
.thenTry([mountPromise, this](Try<FsChannel*>&& channel) {
.thenTry([mountPromise](Try<FsChannel*>&& channel) {
if (channel.hasException()) {
mountPromise->setException(channel.exception());
return makeFuture<FsChannel*>(channel.exception());
@ -1230,7 +1235,6 @@ folly::Future<EdenMount::channelType> EdenMount::channelMount(bool readOnly) {
return makeFuture(channel);
});
#else
AbsolutePath mountPath = getPath();
return serverState_->getPrivHelper()
->fuseMount(mountPath.stringPiece(), readOnly)
.thenTry(

View File

@ -18,8 +18,6 @@
#include "eden/fs/win/mount/Enumerator.h"
#include "eden/fs/win/utils/Guid.h"
constexpr uint32_t kDispatcherCode = 0x1155aaff;
namespace facebook {
namespace eden {
class EdenMount;
@ -66,15 +64,6 @@ class EdenDispatcher {
PCWSTR destinationFileName,
PRJ_NOTIFICATION_PARAMETERS& notificationParameters) noexcept;
//
// Pointer to the dispatcher will be returned from the underlying file system.
// isValidDispatcher() can be used to verify that it is a correct pointer.
//
bool isValidDispatcher() const {
return (verificationCode_ == kDispatcherCode);
}
private:
// The EdenMount that owns this EdenDispatcher.
EdenMount* const mount_;
@ -83,8 +72,6 @@ class EdenDispatcher {
folly::Synchronized<folly::F14FastMap<Guid, Enumerator>> enumSessions_;
const std::string dotEdenConfig_;
const uint32_t verificationCode_ = kDispatcherCode;
};
} // namespace eden

View File

@ -21,10 +21,7 @@ class FsChannel {
FsChannel(){};
virtual ~FsChannel() = default;
virtual void start(
bool readOnly,
EdenDispatcher* dispatcher,
bool useNegativePathCaching) = 0;
virtual void start(bool readOnly, bool useNegativePathCaching) = 0;
virtual void stop() = 0;
virtual void removeCachedFile(RelativePathPiece path) = 0;

View File

@ -17,10 +17,10 @@ using folly::sformat;
namespace {
using facebook::eden::EdenDispatcher;
using facebook::eden::exceptionToHResult;
using facebook::eden::Guid;
using facebook::eden::InodeMetadata;
using facebook::eden::PrjfsChannel;
using facebook::eden::RelativePath;
using facebook::eden::win32ErrorToString;
@ -33,16 +33,14 @@ using facebook::eden::win32ErrorToString;
} \
} while (false)
static EdenDispatcher* getDispatcher(
const PRJ_CALLBACK_DATA* callbackData) noexcept {
PrjfsChannel* getChannel(const PRJ_CALLBACK_DATA* callbackData) noexcept {
DCHECK(callbackData);
auto dispatcher = static_cast<EdenDispatcher*>(callbackData->InstanceContext);
DCHECK(dispatcher);
DCHECK(dispatcher->isValidDispatcher());
return dispatcher;
auto channel = static_cast<PrjfsChannel*>(callbackData->InstanceContext);
DCHECK(channel);
return channel;
}
static HRESULT startEnumeration(
HRESULT startEnumeration(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
@ -50,7 +48,8 @@ static HRESULT startEnumeration(
try {
auto path = RelativePath(callbackData->FilePathName);
auto guid = Guid(*enumerationId);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->opendir(std::move(path), std::move(guid))
.thenValue([](auto&&) { return S_OK; })
.thenError(
@ -64,20 +63,23 @@ static HRESULT startEnumeration(
}
}
static HRESULT endEnumeration(
HRESULT endEnumeration(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
return getDispatcher(callbackData)->endEnumeration(*enumerationId);
return getChannel(callbackData)
->getDispatcher()
->endEnumeration(*enumerationId);
}
static HRESULT getEnumerationData(
HRESULT getEnumerationData(
const PRJ_CALLBACK_DATA* callbackData,
const GUID* enumerationId,
PCWSTR searchExpression,
PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->getEnumerationData(
*callbackData,
*enumerationId,
@ -85,13 +87,13 @@ static HRESULT getEnumerationData(
dirEntryBufferHandle);
}
static HRESULT getPlaceholderInfo(
const PRJ_CALLBACK_DATA* callbackData) noexcept {
HRESULT getPlaceholderInfo(const PRJ_CALLBACK_DATA* callbackData) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
try {
auto path = RelativePath(callbackData->FilePathName);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->lookup(std::move(path))
.thenValue([context = callbackData->NamespaceVirtualizationContext](
const std::optional<InodeMetadata>&& optMetadata) {
@ -131,12 +133,13 @@ static HRESULT getPlaceholderInfo(
}
}
static HRESULT queryFileName(const PRJ_CALLBACK_DATA* callbackData) noexcept {
HRESULT queryFileName(const PRJ_CALLBACK_DATA* callbackData) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
try {
auto path = RelativePath(callbackData->FilePathName);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->access(std::move(path))
.thenValue([](bool present) {
if (present) {
@ -154,23 +157,25 @@ static HRESULT queryFileName(const PRJ_CALLBACK_DATA* callbackData) noexcept {
}
}
static HRESULT getFileData(
HRESULT getFileData(
const PRJ_CALLBACK_DATA* callbackData,
UINT64 byteOffset,
UINT32 length) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->getFileData(*callbackData, byteOffset, length);
}
static HRESULT notification(
HRESULT notification(
const PRJ_CALLBACK_DATA* callbackData,
BOOLEAN isDirectory,
PRJ_NOTIFICATION notificationType,
PCWSTR destinationFileName,
PRJ_NOTIFICATION_PARAMETERS* notificationParameters) noexcept {
BAIL_ON_RECURSIVE_CALL(callbackData);
return getDispatcher(callbackData)
return getChannel(callbackData)
->getDispatcher()
->notification(
*callbackData,
isDirectory,
@ -183,8 +188,14 @@ static HRESULT notification(
namespace facebook {
namespace eden {
PrjfsChannel::PrjfsChannel(EdenMount* mount)
: mountPath_(mount->getPath()), mountId_{Guid::generate()} {}
PrjfsChannel::PrjfsChannel(
AbsolutePathPiece mountPath,
EdenDispatcher* const dispatcher,
std::shared_ptr<ProcessNameCache> processNameCache)
: mountPath_(mountPath),
dispatcher_(dispatcher),
mountId_(Guid::generate()),
processAccessLog_(std::move(processNameCache)) {}
PrjfsChannel::~PrjfsChannel() {
if (isRunning_) {
@ -192,10 +203,7 @@ PrjfsChannel::~PrjfsChannel() {
}
}
void PrjfsChannel::start(
bool readOnly,
EdenDispatcher* dispatcher,
bool useNegativePathCaching) {
void PrjfsChannel::start(bool readOnly, bool useNegativePathCaching) {
if (readOnly) {
NOT_IMPLEMENTED();
}
@ -229,7 +237,6 @@ void PrjfsChannel::start(
}
XLOG(INFO) << "Starting PrjfsChannel for: " << mountPath_;
DCHECK(dispatcher->isValidDispatcher());
auto winPath = mountPath_.wide();
@ -243,7 +250,7 @@ void PrjfsChannel::start(
}
result = PrjStartVirtualizing(
winPath.c_str(), &callbacks, dispatcher, &startOpts, &mountChannel_);
winPath.c_str(), &callbacks, this, &startOpts, &mountChannel_);
if (FAILED(result)) {
throw makeHResultErrorExplicit(result, "Failed to start the mount point");

View File

@ -11,6 +11,7 @@
#include <ProjectedFSLib.h>
#include "eden/fs/utils/PathFuncs.h"
#include "eden/fs/utils/ProcessAccessLog.h"
#include "eden/fs/win/mount/FsChannel.h"
#include "eden/fs/win/utils/Guid.h"
@ -26,10 +27,13 @@ class PrjfsChannel : public FsChannel {
explicit PrjfsChannel() = delete;
PrjfsChannel(EdenMount* mount);
PrjfsChannel(
AbsolutePathPiece mountPath,
EdenDispatcher* const dispatcher,
std::shared_ptr<ProcessNameCache> processNameCache);
~PrjfsChannel();
void
start(bool readOnly, EdenDispatcher* dispatcher, bool useNegativePathCaching);
void start(bool readOnly, bool useNegativePathCaching);
void stop();
folly::SemiFuture<FsChannel::StopData> getStopFuture() override;
@ -44,17 +48,28 @@ class PrjfsChannel : public FsChannel {
void flushNegativePathCache() override;
EdenDispatcher* getDispatcher() {
return dispatcher_;
}
ProcessAccessLog& getProcessAccessLog() {
return processAccessLog_;
}
private:
//
// Channel to talk to projectedFS.
//
PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT mountChannel_{nullptr};
const AbsolutePath& mountPath_;
const AbsolutePath mountPath_;
EdenDispatcher* const dispatcher_{nullptr};
Guid mountId_;
bool isRunning_{false};
bool useNegativePathCaching_{true};
folly::Promise<FsChannel::StopData> stopPromise_;
ProcessAccessLog processAccessLog_;
};
} // namespace eden