mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
dfcc656491
Summary: All future reads to these files will error until the file metadata caches are cleared. This diff triggers a delayed invalidation after a file is read with the incorrect size. This makes the file accessible again. It's possible (though it doesn't always happen) that EdenFS's internal state could be inocorrect for the file. a future `eden doctor` run will be able to fix it up. Reviewed By: MichaelCuevas Differential Revision: D52278628 fbshipit-source-id: 580746bb91d21c79f87d16d5e442843617ac779c
87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#include "folly/portability/Windows.h"
|
|
|
|
#include <ProjectedFSLib.h> // @manual
|
|
#include "eden/fs/inodes/RequestContext.h"
|
|
#include "eden/fs/prjfs/PrjfsChannel.h"
|
|
#include "eden/fs/utils/ImmediateFuture.h"
|
|
#include "eden/fs/utils/PathFuncs.h"
|
|
|
|
namespace facebook::eden {
|
|
|
|
class PrjfsObjectFetchContext : public FsObjectFetchContext {
|
|
public:
|
|
PrjfsObjectFetchContext(ProcessId pid) : pid_{pid} {}
|
|
|
|
OptionalProcessId getClientPid() const override {
|
|
return pid_;
|
|
}
|
|
|
|
private:
|
|
ProcessId pid_;
|
|
};
|
|
|
|
class PrjfsRequestContext : public RequestContext {
|
|
public:
|
|
PrjfsRequestContext(const PrjfsRequestContext&) = delete;
|
|
PrjfsRequestContext& operator=(const PrjfsRequestContext&) = delete;
|
|
PrjfsRequestContext(PrjfsRequestContext&&) = delete;
|
|
PrjfsRequestContext& operator=(PrjfsRequestContext&&) = delete;
|
|
|
|
explicit PrjfsRequestContext(
|
|
folly::ReadMostlySharedPtr<PrjfsChannelInner> channel,
|
|
const PRJ_CALLBACK_DATA& prjfsData)
|
|
: RequestContext(
|
|
channel->getProcessAccessLog(),
|
|
makeRefPtr<PrjfsObjectFetchContext>(
|
|
ProcessId{prjfsData.TriggeringProcessId})),
|
|
channel_(std::move(channel)),
|
|
commandId_(prjfsData.CommandId) {}
|
|
|
|
folly::ReadMostlyWeakPtr<PrjfsChannelInner> getChannelForAsyncUse() {
|
|
return folly::ReadMostlyWeakPtr<PrjfsChannelInner>{channel_};
|
|
}
|
|
|
|
ImmediateFuture<folly::Unit> catchErrors(ImmediateFuture<folly::Unit>&& fut) {
|
|
return std::move(fut).thenTry([this](folly::Try<folly::Unit>&& try_) {
|
|
auto result = tryToHResult(try_);
|
|
if (result != S_OK) {
|
|
sendError(result);
|
|
}
|
|
});
|
|
}
|
|
|
|
void sendSuccess() const {
|
|
return channel_->sendSuccess(commandId_, nullptr);
|
|
}
|
|
|
|
void sendNotificationSuccess() const {
|
|
PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS extra{};
|
|
extra.CommandType = PRJ_COMPLETE_COMMAND_TYPE_NOTIFICATION;
|
|
return channel_->sendSuccess(commandId_, &extra);
|
|
}
|
|
|
|
void sendEnumerationSuccess(PRJ_DIR_ENTRY_BUFFER_HANDLE buffer) const {
|
|
PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS extra{};
|
|
extra.CommandType = PRJ_COMPLETE_COMMAND_TYPE_ENUMERATION;
|
|
extra.Enumeration.DirEntryBufferHandle = buffer;
|
|
return channel_->sendSuccess(commandId_, &extra);
|
|
}
|
|
|
|
void sendError(HRESULT result) const {
|
|
return channel_->sendError(commandId_, result);
|
|
}
|
|
|
|
private:
|
|
folly::ReadMostlySharedPtr<PrjfsChannelInner> channel_;
|
|
int32_t commandId_;
|
|
};
|
|
|
|
} // namespace facebook::eden
|