sapling/eden/fs/utils/SystemError.h
Xavier Deguillard 159e446d4d inodes: fix checkout with concurrent recursive grep
Summary:
The checkout code was designed with the assumption that concurrent reads/writes
to the working copy would block on locks that checkout holds, thus preventing
races. On Windows, this assumption is slightly broken as reads to the working
copy are served by the tree hierarchy not by the inode hierarchy. Reads are
then reflected back to the inode hierarchy in a background manner to increment
the FS refcount. If, somehow a directory is read at the same time as the
corresponding directory entry for it is being invalidated in checkout, checkout
will attempt to invalidate the directory, but since the directory isn't empty
the invalidation would fail, failing checkout.

To solve this, we could simply pretend that the directory is loaded and
recursively run checkout on it.

Reviewed By: kmancini

Differential Revision: D39596117

fbshipit-source-id: 95a42553b8779d904f57f9d168197398f5d45436
2022-10-18 12:32:52 -07:00

46 lines
1.3 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.
*/
#pragma once
#include <eden/common/utils/WinError.h>
#include <system_error>
namespace facebook::eden {
/**
* Return true if this exception contains an errno value in ex.code().value()
*/
inline bool isErrnoError(const std::system_error& ex) {
// std::generic_category is the correct category to represent errno values.
// However folly/Exception.h unfortunately throws errno values as
// std::system_category for now.
return (
ex.code().category() == std::generic_category() ||
ex.code().category() == std::system_category());
}
/**
* Return true if this exception is equivalent to an ENOENT error code.
*/
inline bool isEnoent(const std::system_error& ex) {
auto ret = isErrnoError(ex) && ex.code().value() == ENOENT;
#ifdef _WIN32
ret = ret ||
(ex.code().category() == Win32ErrorCategory::get() &&
(ex.code().value() == ERROR_PATH_NOT_FOUND ||
ex.code().value() == ERROR_FILE_NOT_FOUND));
#endif
return ret;
}
inline bool isEnotempty(const std::system_error& ex) {
return isErrnoError(ex) && ex.code().value() == ENOTEMPTY;
}
} // namespace facebook::eden