sapling/eden/fs/prjfs/PrjfsRequestContext.h
Katie Mancini dfcc656491 invalidate after a torn read so the file is accessible
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
2024-02-22 19:34:50 -08:00

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