2016-05-12 23:43:17 +03:00
|
|
|
/*
|
2017-01-21 09:02:33 +03:00
|
|
|
* Copyright (c) 2016-present, Facebook, Inc.
|
2016-05-12 23:43:17 +03:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#pragma once
|
2017-07-01 05:00:03 +03:00
|
|
|
#include <folly/File.h>
|
2016-09-10 02:56:02 +03:00
|
|
|
#include <folly/Optional.h>
|
2017-02-11 01:16:00 +03:00
|
|
|
#include <folly/Range.h>
|
2016-09-10 02:56:02 +03:00
|
|
|
#include "TreeInode.h"
|
2017-04-14 21:31:48 +03:00
|
|
|
#include "eden/fs/utils/DirType.h"
|
|
|
|
#include "eden/fs/utils/PathFuncs.h"
|
|
|
|
#include "eden/fs/utils/PathMap.h"
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
namespace facebook {
|
|
|
|
namespace eden {
|
|
|
|
|
2017-02-11 01:16:00 +03:00
|
|
|
namespace overlay {
|
|
|
|
class OverlayDir;
|
|
|
|
}
|
|
|
|
|
2018-03-08 09:57:38 +03:00
|
|
|
class InodeMap;
|
|
|
|
|
2016-05-12 23:43:17 +03:00
|
|
|
/** Manages the write overlay storage area.
|
|
|
|
*
|
|
|
|
* The overlay is where we store files that are not yet part of a snapshot.
|
|
|
|
*
|
|
|
|
* The contents of this storage layer are overlaid on top of the object store
|
|
|
|
* snapshot that is active in a given mount point.
|
|
|
|
*
|
|
|
|
* There is one overlay area associated with each eden client instance.
|
|
|
|
*
|
2016-09-10 02:56:00 +03:00
|
|
|
* We use the Overlay to manage mutating the structure of the checkout;
|
|
|
|
* each time we create or delete a directory entry, we do so through
|
|
|
|
* the overlay class.
|
2016-05-12 23:43:17 +03:00
|
|
|
*
|
2016-09-10 02:56:00 +03:00
|
|
|
* The Overlay class keeps track of the mutated tree; if we mutate some
|
|
|
|
* file "foo/bar/baz" then the Overlay records metadata about the list
|
|
|
|
* of files in the root, the list of files in "foo", the list of files in
|
|
|
|
* "foo/bar" and finally materializes "foo/bar/baz".
|
2016-05-12 23:43:17 +03:00
|
|
|
*/
|
|
|
|
class Overlay {
|
|
|
|
public:
|
|
|
|
explicit Overlay(AbsolutePathPiece localDir);
|
|
|
|
|
2016-09-10 02:56:00 +03:00
|
|
|
/** Returns the path to the root of the Overlay storage area */
|
2016-05-12 23:43:17 +03:00
|
|
|
const AbsolutePath& getLocalDir() const;
|
|
|
|
|
2018-03-20 03:01:15 +03:00
|
|
|
void saveOverlayDir(InodeNumber inodeNumber, const TreeInode::Dir& dir) const;
|
2018-03-24 04:17:05 +03:00
|
|
|
|
2018-01-03 03:25:03 +03:00
|
|
|
folly::Optional<TreeInode::Dir> loadOverlayDir(
|
2018-03-20 03:01:15 +03:00
|
|
|
InodeNumber inodeNumber,
|
2018-03-08 09:57:38 +03:00
|
|
|
InodeMap* inodeMap) const;
|
2016-05-12 23:43:17 +03:00
|
|
|
|
2018-03-20 03:01:15 +03:00
|
|
|
void removeOverlayData(InodeNumber inodeNumber) const;
|
2016-09-10 02:56:02 +03:00
|
|
|
|
2017-02-11 01:16:00 +03:00
|
|
|
/**
|
|
|
|
* Get the path to the overlay file for the given inode
|
|
|
|
*/
|
2018-03-20 03:01:15 +03:00
|
|
|
AbsolutePath getFilePath(InodeNumber inodeNumber) const;
|
2017-07-04 10:18:17 +03:00
|
|
|
/**
|
|
|
|
* Creates header for the files stored in Overlay
|
|
|
|
*/
|
|
|
|
static folly::IOBuf createHeader(
|
|
|
|
folly::StringPiece identifier,
|
|
|
|
uint32_t version,
|
2018-02-08 02:01:01 +03:00
|
|
|
const InodeTimestamps& timestamps);
|
2017-02-11 01:16:00 +03:00
|
|
|
|
2017-07-14 03:11:36 +03:00
|
|
|
/**
|
|
|
|
* Helper function that opens an existing overlay file,
|
2017-08-05 06:14:18 +03:00
|
|
|
* checks if the file has valid header
|
|
|
|
* populates st_atim, st_mtim, st_ctim and returns the file.
|
2017-07-14 03:11:36 +03:00
|
|
|
*/
|
2017-08-05 06:14:18 +03:00
|
|
|
static folly::File openFile(
|
|
|
|
folly::StringPiece filePath,
|
|
|
|
folly::StringPiece headerId,
|
2018-02-01 23:21:03 +03:00
|
|
|
InodeTimestamps& timestamps);
|
2017-07-14 03:11:36 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function that creates a new overlay file and adds header to it
|
|
|
|
*/
|
2018-03-20 03:01:15 +03:00
|
|
|
folly::File createOverlayFile(InodeNumber childNumber, timespec ctime);
|
2017-07-14 03:11:36 +03:00
|
|
|
|
2017-08-05 06:14:18 +03:00
|
|
|
/**
|
|
|
|
* Updates the timestamps of an overlay file appropriately
|
|
|
|
* while unloading an inode.
|
|
|
|
*/
|
2017-08-11 21:34:52 +03:00
|
|
|
static void updateTimestampToHeader(
|
|
|
|
int fd,
|
2018-02-01 23:21:03 +03:00
|
|
|
const InodeTimestamps& timeStamps);
|
2017-08-05 06:14:18 +03:00
|
|
|
|
2017-02-11 01:16:00 +03:00
|
|
|
/**
|
|
|
|
* Get the maximum inode number stored in the overlay.
|
|
|
|
*
|
|
|
|
* This is called when opening a mount point, to make sure that new inodes
|
|
|
|
* handed out from this point forwards are always greater than any inodes
|
|
|
|
* already tracked in the overlay.
|
|
|
|
*/
|
2018-03-20 03:01:15 +03:00
|
|
|
InodeNumber getMaxRecordedInode();
|
2016-09-10 02:56:02 +03:00
|
|
|
|
2017-07-14 03:11:36 +03:00
|
|
|
/**
|
|
|
|
* Constants for an header in overlay file.
|
|
|
|
*/
|
|
|
|
static constexpr folly::StringPiece kHeaderIdentifierDir{"OVDR"};
|
|
|
|
static constexpr folly::StringPiece kHeaderIdentifierFile{"OVFL"};
|
|
|
|
static constexpr uint32_t kHeaderVersion = 1;
|
|
|
|
static constexpr size_t kHeaderLength = 64;
|
|
|
|
|
2016-09-10 02:56:00 +03:00
|
|
|
private:
|
2017-02-11 01:16:00 +03:00
|
|
|
void initOverlay();
|
|
|
|
bool isOldFormatOverlay() const;
|
|
|
|
void readExistingOverlay(int infoFD);
|
|
|
|
void initNewOverlay();
|
|
|
|
folly::Optional<overlay::OverlayDir> deserializeOverlayDir(
|
2018-03-20 03:01:15 +03:00
|
|
|
InodeNumber inodeNumber,
|
2018-02-01 23:21:03 +03:00
|
|
|
InodeTimestamps& timeStamps) const;
|
2017-07-14 03:11:36 +03:00
|
|
|
/**
|
|
|
|
* Helper function to add header to the overlay file
|
|
|
|
*/
|
2017-11-21 20:14:34 +03:00
|
|
|
static void addHeaderToOverlayFile(int fd, timespec ctime);
|
2017-02-11 01:16:00 +03:00
|
|
|
|
2017-08-05 06:14:18 +03:00
|
|
|
/**
|
|
|
|
* Parses, validates and reads Timestamps from the header.
|
|
|
|
*/
|
|
|
|
static void parseHeader(
|
|
|
|
folly::StringPiece header,
|
|
|
|
folly::StringPiece headerId,
|
2018-02-01 23:21:03 +03:00
|
|
|
InodeTimestamps& timeStamps);
|
2017-08-05 06:14:18 +03:00
|
|
|
|
2016-09-10 02:56:00 +03:00
|
|
|
/** path to ".eden/CLIENT/local" */
|
2016-05-12 23:43:17 +03:00
|
|
|
AbsolutePath localDir_;
|
2017-07-01 05:00:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* An open file descriptor to the overlay info file.
|
|
|
|
*
|
|
|
|
* This is primarily used to hold a lock on the overlay for as long as we are
|
|
|
|
* using it. We want to ensure that only one eden process
|
|
|
|
*/
|
|
|
|
folly::File infoFile_;
|
2016-05-12 23:43:17 +03:00
|
|
|
};
|
2017-11-04 01:58:04 +03:00
|
|
|
} // namespace eden
|
|
|
|
} // namespace facebook
|