to support arbitrary object IDs in graceful restart, differentiate between no object ID and the empty ID

Summary:
To avoid shutting the door on whether a BackingStore might want to
support a valid but empty ObjectID, change the hash property in
SerializedInodeMapEntry to optional.

Reviewed By: kmancini

Differential Revision: D32977106

fbshipit-source-id: 8549d2f7e187bfa5e642f8231ccbaebbc6a1ac39
This commit is contained in:
Chad Austin 2022-03-03 12:11:31 -08:00 committed by Facebook GitHub Bot
parent 1dba9e477c
commit 92840f31bd
3 changed files with 22 additions and 16 deletions

View File

@ -186,6 +186,18 @@ void InodeMap::initializeFromTakeover(
throw std::runtime_error(message);
}
std::optional<ObjectId> hash;
if (entry.hash_ref().has_value()) {
const std::string& value = entry.hash_ref().value();
if (value.empty()) {
// LEGACY: Old versions of EdenFS sent the empty string to mean
// materialized. When a BackingStore wants to support the empty ObjectId
// as a valid identifier, remove this code path.
hash = std::nullopt;
} else {
hash = ObjectId{value};
}
}
initializeUnloadedInode(
data,
InodeNumber::fromThrift(*entry.parentInode_ref()),
@ -193,9 +205,7 @@ void InodeMap::initializeFromTakeover(
PathComponentPiece{*entry.name_ref()},
*entry.isUnlinked_ref(),
*entry.mode_ref(),
entry.hash_ref()->empty() ? std::nullopt
: std::optional<ObjectId>{folly::ByteRange{
folly::StringPiece{*entry.hash_ref()}}},
std::move(hash),
folly::to<uint32_t>(*entry.numFsReferences_ref()));
}
@ -889,7 +899,10 @@ Future<SerializedInodeMap> InodeMap::shutdown(
serializedEntry.name_ref() = entry.name.stringPiece().str();
serializedEntry.isUnlinked_ref() = entry.isUnlinked;
serializedEntry.numFsReferences_ref() = entry.numFsReferences;
serializedEntry.hash_ref() = thriftHash(entry.hash);
if (entry.hash.has_value()) {
serializedEntry.hash_ref() = entry.hash.value().asString();
}
// If entry.hash is empty, the inode is not materialized.
serializedEntry.mode_ref() = entry.mode;
result.unloadedInodes_ref()->emplace_back(std::move(serializedEntry));

View File

@ -35,17 +35,6 @@ inline std::string thriftHash20(const Hash20& hash) {
return folly::StringPiece{hash.getBytes()}.str();
}
/**
* Convert an optional<ObjectId> to a std::string to be returned via thrift
* as a thrift BinaryHash data type.
*/
inline std::string thriftHash(const std::optional<ObjectId>& hash) {
if (hash.has_value()) {
return thriftHash(hash.value());
}
return std::string{};
}
/**
* Convert thrift BinaryHash data type into a Hash20 object.
*

View File

@ -19,7 +19,11 @@ struct SerializedInodeMapEntry {
3: string name;
4: bool isUnlinked;
5: i64 numFsReferences;
6: string hash;
// If unset, the inode is materialized.
// LEGACY: if the empty string, the inode is materialized. In the future,
// the semantics will change here, as a BackingStore might use the empty
// string as a valid ID.
6: optional string hash;
7: i32 mode;
}