sapling/eden/fs/inodes/OverlayFile.h
Genevieve (Genna) Helsel e0d0c0fae0 extend OverlayFile to hold folly::File or InodeNumber
Summary:
In preparation for `LMDBFileContentStore`, this diff extends the OverlayFile class to hold either a `folly::File` or an `InodeNumber`.

`FsFileContentStore` returns a `folly::File` which wraps an open `fd` to the raw file on disk. This allows for direct manipulation of the data without a trip through the `FsFileContentStore`. It also acts as a way to refcount any open IO requests to the underlying overlay storage (see: D17973664)

`LMDBFileContentStore` doesn't have the ability to return a file descriptor for direct manipulation, so instead it will return its key and operations to the `OverlayFile` will query `LMDBFileContentStore` on demand using the given `InodeNumber`.

In theory, `LMDBFileContentStore` doesn't need the concept of an `OverlayFile` since it doesn't need to refcount open file handles, but adapting the class to work with the `LMDBFileContentStore` model is cleaner than working around `OverlayFile`/`OverlayFileAccess` class.

The following images depict the two different architectures

{F1075774500}

 {F1075774523}

Reviewed By: kmancini

Differential Revision: D48569910

fbshipit-source-id: 2f171ede0c4ac168ca01bb1c65dc9d401edc4681
2023-10-10 11:03:56 -07:00

71 lines
2.1 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 <folly/Expected.h>
#include <folly/File.h>
#include <folly/portability/SysUio.h>
#include <variant>
#include "eden/common/utils/FileOffset.h"
#include "eden/fs/inodes/InodeNumber.h"
namespace folly {
class File;
}
namespace facebook::eden {
class Overlay;
/**
* Class to manage IO reference counting for an Overlay to support closing the
* Overlay class even if it is still in use.
*
* If an OverlayFile was created from a folly::File, this class will manage
* reference counting for the underlying on-disk Overlay storage.
*/
class OverlayFile {
public:
OverlayFile() = default;
explicit OverlayFile(folly::File file, std::weak_ptr<Overlay> overlay);
explicit OverlayFile(InodeNumber ino, std::weak_ptr<Overlay> overlay);
explicit OverlayFile(
std::variant<folly::File, InodeNumber> data,
std::weak_ptr<Overlay> overlay);
OverlayFile(OverlayFile&&) = default;
OverlayFile& operator=(OverlayFile&&) = default;
folly::Expected<struct stat, int> fstat() const;
folly::Expected<ssize_t, int>
preadNoInt(void* buf, size_t n, FileOffset offset) const;
folly::Expected<FileOffset, int> lseek(FileOffset offset, int whence) const;
folly::Expected<ssize_t, int>
pwritev(const iovec* iov, int iovcnt, FileOffset offset) const;
folly::Expected<int, int> ftruncate(FileOffset length) const;
folly::Expected<int, int> fsync() const;
folly::Expected<int, int> fallocate(FileOffset offset, FileOffset length)
const;
folly::Expected<int, int> fdatasync() const;
folly::Expected<std::string, int> readFile() const;
private:
OverlayFile(const OverlayFile&) = delete;
OverlayFile& operator=(const OverlayFile&) = delete;
/**
* This will contain a folly::File if created from an Overlay with type
* InodeCatalogType::Legacy or an InodeNumber if created from an Overlay with
* type InodeCatalogType::LMDB
*/
std::variant<folly::File, InodeNumber> data_;
std::weak_ptr<Overlay> overlay_;
};
} // namespace facebook::eden