Commit Graph

576 Commits

Author SHA1 Message Date
Chad Austin
d4e186f995 store FileInode and TreeInode timestamps in the InodeTable
Summary: Store tree and file timestamps in the InodeTable so they persist across runs.

Reviewed By: simpkins

Differential Revision: D6891479

fbshipit-source-id: 1c9e6266375aceeaf293a81e73cf7f5334dbc32d
2018-05-22 11:22:19 -07:00
Yedidya Feldblum
4c0c008774 Split Futures exceptions by Promise vs Future
Summary:
[Folly] Split Futures exceptions by `Promise` vs `Future`.

* Move `Promise` exceptions into the `Promise` header.
* Move `Future` exceptions into the `Future` header.
* Split `NoState` into `PromiseInvalid` and `FutureInvalid`.
* Remove the newly-empty exceptions header.

Reviewed By: andriigrynenko

Differential Revision: D7966499

fbshipit-source-id: 2dc6d2a941493979ebf47b3e70e5cf6a6fbd33cf
2018-05-18 18:07:19 -07:00
Chad Austin
22e46cfe74 standardize on std::chrono_literals
Summary:
This is not at all clear from cppreference.com, but per
https://www.youtube.com/watch?v=dTeKf5Oek2c, it sounds to me like
recommended practice is to either:

`using namespace std::chrono_literals` (or string_literals or
whatever) to pull in a focused set of literals.

or

`using namespace std::literals` to pull in all standard literals.

or

`using namespace std` to pull in everything.

`using namespace std::literals::chrono_literals` is unnecessarily
verbose.

Adopt those standards in Eden.

Reviewed By: simpkins

Differential Revision: D8060944

fbshipit-source-id: 4d9dd4329698b7ff5e5c81b5b28780ca4d81a2a1
2018-05-18 16:51:15 -07:00
Chad Austin
2dc2a16cf2 relax InodeTable locking
Summary:
This allows multiple inodes to update their metadata simultaneously
without contending on InodeTable's locks.

Reviewed By: simpkins

Differential Revision: D7885245

fbshipit-source-id: cc8ab6cd90b7424beec314a115852e08b64026ae
2018-05-18 15:21:16 -07:00
Adam Simpkins
684fa29593 update folly::Init to call folly::initLogging()
Summary:
Update the folly::Init code to define a `--logging` command line flag, and call
`folly::initLoggingOrDie()` with the value of this command line during
initialization.

This is similar to the existing code that initializes the glog library.
(Programs can use both glog and folly logging together in the same program, and
I expect that many programs will do so as parts get converted to folly::logging
and parts remain using glog.)

Reviewed By: yfeldblum

Differential Revision: D7827344

fbshipit-source-id: 8aa239fbad43bc0b551cbe40cad7b92fa97fcdde
2018-05-15 12:38:01 -07:00
Chad Austin
abe68df349 Fix replacing an empty directory with another directory
Summary:
While running the secfs filesystem validation tests against Eden, I
discovered a test that caused the eden process to abort. I bisected
and found that D7451330 regressed renaming a directory onto an empty
one. This fixes that case.

Reviewed By: simpkins

Differential Revision: D7945727

fbshipit-source-id: 592ede1b391528c02cd12b2b6ebbf3733fe8f503
2018-05-11 14:52:07 -07:00
Chad Austin
72be488e3d add convenient operator literals for the various path piece types
Summary:
I got tired of typing PathComponentPiece{"..."} in tests so here are
some operator literals.

Reviewed By: simpkins

Differential Revision: D7956732

fbshipit-source-id: 85d9f3fd725853a54da9e70fc659bd7eb9e0862c
2018-05-11 14:52:07 -07:00
Chad Austin
577f6960d7 remove legacy Overlay code
Summary: This old Overlay code is no longer necessary.

Reviewed By: simpkins

Differential Revision: D7903912

fbshipit-source-id: 4a39d6ce7d1f6f81eb13715f2d5d17b22c10d413
2018-05-09 17:06:43 -07:00
Chad Austin
fd20487c7b implement an InodeTable for storing persistent per-inode info decoupled from memory
Summary:
A persistent (but notably non-durable) mapping from inode
number to a fixed-size record stored in a memory-mapped file.  The two
primary goals here are:

1. efficiently (and lazily) reify timestamps for inodes that aren't in the overlay
2. allow the kernel's page cache to drop pages under memory pressure

Reviewed By: simpkins

Differential Revision: D6877361

fbshipit-source-id: a4366b12e21e2bf483c83069cd93ef150829b2ac
2018-05-09 16:50:53 -07:00
Chad Austin
d9a6089dd5 mark parts of EdenTimestamp noexcept
Summary:
Make it clear (especially for the upcoming InodeMetadata struct) which
operations with EdenTimestamp and InodeTimestamps will never throw.

Reviewed By: simpkins

Differential Revision: D7920219

fbshipit-source-id: 5917da51b8128455893a1480def6f2c1c8de13d4
2018-05-09 16:50:52 -07:00
Chad Austin
52776c3666 folly::Unit{} -> folly::unit
Summary:
Per yfeldblum's comment in D7886046, we can use folly::unit instead
of folly::Unit{}. We weren't using folly::unit anywhere, so this diff
replaces folly::Unit{} elsewhere in the Eden code.

Reviewed By: yfeldblum

Differential Revision: D7913462

fbshipit-source-id: fa6ab44ceb406d38713e0f4649224a74e6e51abd
2018-05-08 13:38:02 -07:00
Michael Bolin
b4f3c70c6a Distinguish between "renaming" and "replacing" a file in the journal.
Summary:
Historically, we have seen a number of messages like the following in the Eden
logs:

```
Journal for .hg/blackbox.log holds invalid Created, Created sequence
```

Apparently we were getting these invalid sequences because we were not always
recording a "rename" correctly. The "rename" constructor for a `JournalDelta`
assumed that the source path should be included in the list of "removed" files
while the destination path should be included in the list of "created" files.
However, that is not accurate if the destination path already existed before
the user ran `mv`.

Fortunately, we already check whether the destination file exists in
`TreeInode::doRename()`, so it is straightforward to determine whether the
action is a "rename" (destination does not exist) or an "replace" (destination
already exists) and then classify the destination path accordingly.

As demonstrated by the new test introduced in this commit
(`JournalUpdateTest::moveFileReplace`), in the old implementation,
a file that was removed after it was overwritten would not show up as
removed in the merged `JournalDelta`. Because Watchman relies on
`JournalDelta::merge()` via the Thrift method `getFilesChangedSince()`,
this would cause Watchman to report such a file as still existing even
though it was removed.

This definitely caused bugs in Nuclide. It is likely that other tools that rely
on Watchman in Eden (such as Buck) may have also done incorrect things
because of this bug, so this could explain past reported issues.

Reviewed By: simpkins

Differential Revision: D7888249

fbshipit-source-id: 3e57963f27c5421a6175d1a759db8d9597ed76f3
2018-05-07 14:23:13 -07:00
Adam Simpkins
f187baef89 fix bug incorrectly reporting a file as modified
Summary:
When comparing two source control blob hashes, identical hashes can be assumed
to mean that the file contents are equal.  However, differing hashes does not
necessarily mean that the file contents differ.  In particular, mercurial
hashes history metadata in addition to the file contents when computing the
blob hash.

This updates Eden to always compare the file contents when the source control
blob hashes differ, rather than assuming that the file contents are different.

Reviewed By: wez

Differential Revision: D7825900

fbshipit-source-id: e611124a66cdd5c44589f20d1d4665a603286530
2018-04-30 22:10:01 -07:00
Adam Simpkins
8e3c09a99a move folly/experimental/logging to folly/logging/
Summary:
Promote the folly logging code out of the experimental subdirectory.
We have been using this for several months in a few projects and are pretty
happy with it so far.

After moving it out of the experimental/ subdirectory I plan to update
folly::Init() to automatically support configuring it via a `--logging` command
line flag (similar to the initialization it already does today for glog).

Reviewed By: yfeldblum, chadaustin

Differential Revision: D7755455

fbshipit-source-id: 052db34c97f7516728f7cbb1a5ad959def2f6efb
2018-04-30 21:29:29 -07:00
Adam Simpkins
dea514bbef add CMake build files
Summary: Add CMakeFiles to build Eden.

Reviewed By: wez

Differential Revision: D7479587

fbshipit-source-id: 7e0b4a756005dadc3af5c13c36ce22d1dcc15071
2018-04-30 14:37:46 -07:00
Chad Austin
c22dd7924d mark a bunch of folly::Future<folly::Unit> functions with FOLLY_NODISCARD
Summary:
To avoid bugs similar to the ones fixed in D7781691, mark a bunch of
folly::Future<folly::Unit> functions with FOLLY_NODISCARD.

Reviewed By: simpkins

Differential Revision: D7782224

fbshipit-source-id: 23ba42aa63011cc33e5a6e18d5bc6d00403a78d3
2018-04-26 21:00:25 -07:00
Chad Austin
45c33d5cfd Lock down access to the .eden directory after mount startup
Summary:
Disallow any kind of mutation operation inside of the .eden directory.  We had some
code in place to prevent some of this already, but errors (including EPERM) weren't
passed out from unlink and rename out to FUSE.

Reviewed By: simpkins

Differential Revision: D7781691

fbshipit-source-id: aaecf13779eca75d6ee8765fc8bb3727ce9341de
2018-04-26 21:00:25 -07:00
Chad Austin
a9d4c071ef give InodeBase a mode_t instead of dtype_t
Summary: The InodeTable work will homogenize mode_t storage, access, and modification across file and tree inodes.  In preparation, have InodeBase keep track of the initial mode bits instead of a dtype_t.

Reviewed By: simpkins

Differential Revision: D7031924

fbshipit-source-id: f2e6e4467cecfc0ca06ad998cce0af18a99cc251
2018-04-26 16:20:05 -07:00
Chad Austin
981e03c979 clarify getParentBuggy's comment and why TreeInodeDirHandle's use is safe
Summary: Just comments.

Reviewed By: simpkins

Differential Revision: D7749564

fbshipit-source-id: 41d222c8b73970ba77592928522e9f11d508e0cf
2018-04-24 20:27:53 -07:00
Chad Austin
13dc5d1d51 minor prefactoring split out from later diffs
Summary: Also print the inode path if the assertions in EXPECT_FILE_INODE fail.

Reviewed By: simpkins

Differential Revision: D7035517

fbshipit-source-id: 6c50acb588d1c985c7e7a1586c06f04a657698f9
2018-04-24 18:53:19 -07:00
Chad Austin
0338fc77d2 make most of recursivelyRemoveOverlayData async
Summary:
Now that Eden writes tree data into the overlay even when not
materialized, checkouts can be slow as Eden actively tries to forget
allocated inode data for potentially large trees when
kPreciseInodeMemory is false.  This pushes the bulk of that garbage
collection work onto a background thread, making checkouts fast again.

Reviewed By: simpkins

Differential Revision: D7683120

fbshipit-source-id: 2a22e4612a4438b3ed2527670343c49dfcd902bc
2018-04-24 18:53:19 -07:00
Chad Austin
7335196fed helper function for updating the time fields in struct stat
Summary: This gets rid of those pesky #ifdefs in FileInode.cpp and TreeInode.cpp.

Reviewed By: wez

Differential Revision: D7735914

fbshipit-source-id: d810461984e21f72670f43ca2d1b4f5aacbf376e
2018-04-24 13:44:10 -07:00
Adam Simpkins
0195e0f6f0 ensure that the ServerState object outlives all EdenMounts
Summary:
This updates the code to store ServerState using a shared_ptr rather than
having it be an inlined member variable of EdenServer.

Previously EdenMount objects contained a raw pointer to the ServerState, with
the reasoning that the EdenServer object should outlive the EdenMount objects.
It turns out that this is not quite true in practice--EdenMount::destroy() will
normally be called before the EdenServer is destroyed, but this may not
actually destroy the EdenMount object immediately.

This fixes a race condition in the FuseTest.initMount() test that could cause
this test to occasionally fail when run on a heavily loaded system.

Reviewed By: chadaustin

Differential Revision: D7720509

fbshipit-source-id: 056ff5985587c8d8c32c11d17ba637ebd7598677
2018-04-23 13:53:48 -07:00
Chad Austin
d0256aa116 add a test that verifies unloaded, unlinked trees don't leave orphaned data in the overlay
Summary:
I was worried we might leak data in the overlay in this particular
sequence of operations, so here's a test that shows we don't.

Reviewed By: simpkins

Differential Revision: D7663419

fbshipit-source-id: b4b0d08f863fe7b23501e9e4943d18ba0b746e42
2018-04-20 18:52:17 -07:00
Chad Austin
42e2ffad76 immediately save inode numbers when allocating a TreeInode
Summary:
When we start storing permission changes and other inode
metadata keyed on inode number, we will need to remember inode numbers
before they're accessed to handle the case where the Eden process dies
before the inode is unloaded.  Otherwise, data could be left in an
inconsistent state and some writes could be missed.

This change depends on saving (and forgetting) directories being
cheap.

Reviewed By: simpkins

Differential Revision: D7598094

fbshipit-source-id: 9ab127b30a9c09ab62aa08b50c13b3eaa40be60d
2018-04-20 18:52:17 -07:00
Adam Simpkins
5fbe610f05 split the Checkout.modifyConflict test into 3 separate tests
Summary:
Split the modifyConflict() test into 3 separate test functions.  This test
runs the same checks in 54 separate variations (3 path names, 3 checkout types,
with 6 inode load options).

For each variation we set up a new test mount, creating an overlay and
LocalStore on disk.  Simply setting up and tearing down the test mounts can be
expensive if the temporary directory is served from spinning disk.  This causes
this test to occasionally time out when run on our continuous build hosts.

Splitting the test up into 3 separate test functions will effectively give it
3x longer to run, since each test function will have a separate timeout.  This
will also enable these test functions to run in parallel (although that may not
actually help with performance if they are bottlenecked on disk I/O).

Reviewed By: chadaustin

Differential Revision: D7665409

fbshipit-source-id: 4bddd68e75f38b1b6cc2d57512a5b52855f3bade
2018-04-18 14:10:03 -07:00
Chad Austin
ce0739d7f4 remove the fdatasync() from Overlay writes
Summary:
fdatasync() has a substantial cost and is unnecessary given
our durability guarantees (and the fact that most filesystems on Linux
try to avoid data loss in this common write + rename situation anyway)

Reviewed By: simpkins

Differential Revision: D7641131

fbshipit-source-id: d041e7090dc05a4d4400f86cad9501aa8a6988a9
2018-04-16 19:09:06 -07:00
Adam Simpkins
c2d233c7b8 reduce the log level for an overlay message
Summary:
Drop the log level of the "no dir data for inode" message from DBG2 to DBG3 so
we do not have it enabled by default.  (Our default log settings are
eden=DBG2.)

Reviewed By: chadaustin

Differential Revision: D7620918

fbshipit-source-id: 25cf30af08054f3ba879bd57f3841b1035e0c75e
2018-04-13 15:46:02 -07:00
Chad Austin
42808d2ced centralize overlay dir access
Summary:
I'm about to change the code paths through which directories
are saved to and loaded from persistent storage.  To help, consolidate
those operations.

Reviewed By: simpkins

Differential Revision: D7597978

fbshipit-source-id: 9cd20027746b0a372a97b7f5daf07c1b54e6b9ce
2018-04-13 10:58:39 -07:00
Chad Austin
5ed3d0ce28 storage overview doc
Summary:
Add a document that begins to sketch out the various transitions that
our inode data structures make so we can reason about their
correctness

Reviewed By: simpkins

Differential Revision: D7434693

fbshipit-source-id: 5478c108c338ccdadc22e864b077195c8be7d1b7
2018-04-10 16:04:18 -07:00
Adam Simpkins
2ea6c866da avoid unnecessarily saving overlay state on unmount
Summary:
Once a mount point has been unmounted we no longer need to care about
outstanding FUSE reference counts--we can treat them as if they are all zero.

This updates EdenMount to tell the InodeMap when the mount point is unloaded,
and changes InodeMap::unloadInode() to make use of this information when
deciding if it needs to remember the inode information.

Previously InodeMap would save information for inodes with outstanding FUSE
reference counts.  Writing all of this state to the overlay could take a
non-trivial amount of time.

Reviewed By: chadaustin

Differential Revision: D7555998

fbshipit-source-id: 0896f867ce850ab3e61c262776d536de003685ff
2018-04-10 12:56:20 -07:00
Adam Simpkins
c8921d0218 remove alternate EDEN_HAS_COMMON_STATS code paths
Summary:
Remove the EDEN_HAS_COMMON_STATS checks now that the common/stats stubs have
the required APIs needed by Eden.

Reviewed By: wez

Differential Revision: D7479593

fbshipit-source-id: cc3db50288bfea7aefd6c91391ab800628b7978f
2018-04-10 12:19:17 -07:00
Adam Simpkins
00b9a04aa1 rename InodeBase::getRefcount() to debugGetFuseRefcount()
Summary:
Rename `getRefcount()` to `debugGetFuseRefcount()` to make it clear that this
returns the FUSE reference count rather than the pointer refcount, and that
the result should not be used for anything other than debugging or diagnostic
purposes.

There is already a `getFuseRefcount()` method to check the FUSE refcount while
the inode is being unloaded.  The only time it is safe to check the FUSE
refcount for programmatic purposes, and `getFuseRefcount()` has a `DCHECK()` to
help ensure that this is the only time it is called.

(`getFuseRefcount()` also predates `getRefcount()`, which was added for the
`eden debug inode` command in D5277870.)

Reviewed By: chadaustin

Differential Revision: D7555997

fbshipit-source-id: e66f2b3d2b9eb14f8f8878d78978851929198a31
2018-04-09 14:08:13 -07:00
Adam Simpkins
645731a8a0 release the overlay lock when EdenMount::shutdown() completes
Summary:
Change EdenMount to destroy the Overlay object as soon as the `shutdown()`
operation completes.  Previously the Overlay would not get destroyed until
EdenMount::destroy() was called.

During graceful restart we transfer mount information to the new process after
`shutdown()` completes, but potentially before `destroy()` has finished.  This
previously resulted in a race condition where the new process could start
opening the overlay before the old process had released the lock.  This change
should fix that race condition.

Reviewed By: chadaustin

Differential Revision: D7543295

fbshipit-source-id: 82ae33fe6bb0aa9f0a3b010fdd1d350c63442420
2018-04-09 12:21:03 -07:00
Adam Simpkins
7c2d0b13b1 store the Overlay using unique_ptr rather than shared_ptr
Summary: Each Overlay object should be owned only by its EdenMount.

Reviewed By: chadaustin

Differential Revision: D7543294

fbshipit-source-id: 6db40fea31ce298c61d047cba9165887e32926a1
2018-04-09 12:21:03 -07:00
Adam Simpkins
2fedc3bcea update getScmStatus() to require the commit hash as an argument
Summary:
Change getScmStatus() so that callers must explicitly specify the commit to
diff against.  This should help avoid race conditions around commit or checkout
operations where the parent commit has just changed and eden returns status
information against a commit that wasn't what the client was expecting.

This should still maintain backwards compatibility with older clients that do
not send this parameter yet: we will simply receive the hash as an empty string
in this case, and we still provide the old behavior in this case.

Reviewed By: wez

Differential Revision: D7512338

fbshipit-source-id: 1fb4645dda13b9108c66c2daaa802ea3445ac5f2
2018-04-06 12:51:31 -07:00
Chad Austin
625d1868f0 delete saved, stale inode numbers from overlay during checkout
Summary:
Now that D7451330 writes saved inode numbers into the overlay, we
need to make sure they get deleted when checking out between trees.

Reviewed By: simpkins

Differential Revision: D7327942

fbshipit-source-id: 9593c7abe9d2e424b9ca1d9c5a5ab8b285867e6e
2018-04-06 11:05:53 -07:00
Chad Austin
f4a74f6309 Always remember the inode numbers of children when unloading a tree
Summary:
Always remember the inode numbers of children when unloading
a tree.  This fixes a bug where, if a tree is unloaded during a build,
child inode numbers would be regenerated, causing the same header to
be compiled once.  gcc and clang use inode numbers to decide whether
to #include a file that uses #pragma once, so they must remain
consistent while a mount is up.

This is perhaps a bit controversial because it saves _every_ tree,
unconditionally, to the overlay.  I will either stack another diff
that ensures these overlay trees are deleted when checking out to a
new tree or make that change in place here, depending on how urgently
this fix is needed.

Reviewed By: simpkins

Differential Revision: D7451330

fbshipit-source-id: 1c3bc0d55327924c88d1a559d2557cfc158991f2
2018-04-06 11:05:53 -07:00
Chad Austin
debe121eeb add a takeover test to InodeMap
Summary: Add test demonstrating inode numbers are not consistent across takeover.

Reviewed By: simpkins

Differential Revision: D7300867

fbshipit-source-id: 1e142c28ac00b569b96b5a1867bc8632771c2be9
2018-03-30 01:06:50 -07:00
Adam Simpkins
f1d758b5b5 clean up inefficiencies in Overlay code
Summary:
This cleans up the two createOverlayFile() implementations as well as
saveOverlayDir() to all use the same logic for writing out overlay files.  This
new logic is more efficient than some of the old code, as we only open the file
once.

Additionally, this also changes the Overlay code to use openat() and related
APIs when accessing files in the overlay, so that we can specify paths relative
the top-level overlay directory.  This means that all pathnames are guaranteed
to fit in a small path length known at compile time, and we can avoid ever
allocating path names on the heap.

One potential downside of using openat() is that this functionality may not be
available on Mac OS X, so we will likely still need to provide alternate
implementations that do use heap-allocated absolute paths for Mac support.

Reviewed By: chadaustin

Differential Revision: D7411499

fbshipit-source-id: dd76395130dda4c2b9403cce04f4201f6def0d10
2018-03-28 20:52:08 -07:00
Adam Simpkins
2ffefa177e make Overlay::getFilePath() private and add a test case
Summary: Add a test case to confirm the behavior of Overlay::getFilePath().

Reviewed By: chadaustin

Differential Revision: D7411498

fbshipit-source-id: f859f29e252c1c296eb236113ad2a8b0a892db37
2018-03-28 13:13:52 -07:00
Adam Simpkins
f334d7ab79 reduce code duplication in TreeInode create methods
Summary:
Most of the logic in TreeInode::create(), symlink() and mknod() was very
similar.  This adds a TreeInode::createImpl() helper method that these three
functions can share.

This also updates TreeInode::create() to throw EEXIST if the file in question
does exist, rather than using EDEN_BUG().  I believe it is possible (but
unlikely) for this to occur in practice since inode invalidation operations
triggered by a checkout are now processed asynchronously.

Reviewed By: chadaustin

Differential Revision: D7411500

fbshipit-source-id: 85d97995139eee6bff96381561fc28e76d7a2b7c
2018-03-28 13:13:52 -07:00
Adam Simpkins
96a995962f update Overlay APIs to take inode numbers instead of paths
Summary:
Update all Overlay APIs to accept InodeNumbers and compute the path to the
overlay file internally, rather than requiring the caller to pass in the path
to the file inside the overlay.

Reviewed By: chadaustin

Differential Revision: D7411497

fbshipit-source-id: d057babb0b1b8d6c3b9adf1a21b84eed363dffa1
2018-03-28 13:13:51 -07:00
Chad Austin
e56b25df9f remove loading bit from TreeInode::Entry
Summary: After the changes in D7052470 and D7346263, this bit is no longer necessary.

Reviewed By: simpkins

Differential Revision: D7401540

fbshipit-source-id: 04f3ae0376625d4e9584f31932f46774eb5caba4
2018-03-27 13:23:13 -07:00
Adam Simpkins
6b050c7be5 restructure FileInode open refcount management
Summary:
This adds a new LockedState helper class in FileInode to also keep track of
whether or not we are currently holding an refcount on the open file/blob.  The
LockedState object automatically decrements this refcount on destruction.
Alternatively, this refcount can be transferred to a new EdenFileHandle object
when unlocking the state.

Previously most of the internal FileInode code simply used EdenFileHandle
objects to manage this refcount.  However, this is prone to deadlock, since you
have to ensure that EdenFileHandle objects are never destroyed while the state
is already locked.  This new LockedState API makes it harder to have code paths
that may accidentally destroy an EdenFileHandle object while holding the state
lock.

Reviewed By: chadaustin

Differential Revision: D7407423

fbshipit-source-id: 610fcda3220a9f49b734910b7a13e8d68a81a779
2018-03-27 11:23:42 -07:00
Adam Simpkins
b324323ad4 make inode unloading methods non-const
Summary:
Update InodeMap::onInodeUnreferenced() to take a pointer to a non-const
InodeBase.  This allows the methods it calls, including
InodeBase::updateOverlayHeader() to be non-const.

Using non-const InodeBase objects seems to make sense here since the inode is
in the process of being destroyed.

In a future diff I plan to update FileInode::updateOverlayHeader() to share the
same code as normal file methods to ensure that the overlay file is open.  This
modifies the FileInode state's open refcount, so it is useful to have this
method be non-const for that purpose.

Reviewed By: chadaustin

Differential Revision: D7407424

fbshipit-source-id: 541656c7b9b283c5e5650445de5bbdbaae3fc57f
2018-03-27 11:23:42 -07:00
Adam Simpkins
086fc9ac30 send FUSE invalidation requests in a separate thread
Summary:
Update FuseChannel to send all invalidation requests in a separate thread.

This eliminates a deadlock that could previously occur during checkout
operations.  The invalidation requests would block until they could acquire the
kernel's inode lock on the inode in question.  However, the inode lock may
already be held by another thread attempting to perform an unlink() or rename()
call.  These FUSE unlink or rename operations would be blocked waiting on
Eden's mount point rename lock, which was acquired by the checkout operation.

Checkout operations now let the invalidations complete asynchronously, but we
wait for all invalidation operations to complete before indicating to our
caller that the checkout has succeeded.

Reviewed By: chadaustin, wez

Differential Revision: D7404971

fbshipit-source-id: 6fa20c00d054e210eb0258d247d083010557f210
2018-03-27 11:23:42 -07:00
Chad Austin
d217ef6d3e fix opt build
Summary:
D7363180 introduced some shadowed variables whose warnings only broke
the opt build.

Reviewed By: simpkins

Differential Revision: D7401974

fbshipit-source-id: 49c6b16489af0f6000f0714e587fa59f503272a0
2018-03-26 12:42:53 -07:00
Chad Austin
c80f10ad03 decouple whether an entry has an inode number from materialization status
Summary:
Decouple inode number assignment from materialization status.
The idea is that we will always assign entries an inode number and
track whether an entry is materialized otherwise.  This is necessary
to give consistent inode values across remounts.

Reviewed By: simpkins

Differential Revision: D7052470

fbshipit-source-id: 80d3f2a2938463198a3132182537e6223c79d509
2018-03-23 18:21:21 -07:00
Chad Austin
bf31028299 test and fix for takeover bug when trees are referenced across a takeover
Summary:
Verify Eden handles looking up an inode by number after graceful
restart and checkout.

Reviewed By: simpkins

Differential Revision: D7346263

fbshipit-source-id: 876b4837708da9ac31f72c06e7defc797fe126f3
2018-03-23 15:06:22 -07:00
Chad Austin
c176bf06fd simplify startLoadingInode
Summary: Small refactoring prior to a fix in a later diff.

Reviewed By: simpkins

Differential Revision: D7358218

fbshipit-source-id: 198160df1aa0dc65b917c5a96c2998c3675b03fe
2018-03-23 15:06:22 -07:00
Chad Austin
f80dd19454 add a graceful takeover method to TestMount
Summary: Now we can write unit tests for takeover. :)

Reviewed By: simpkins

Differential Revision: D7345419

fbshipit-source-id: 05741dab65016c59109bf190c83be2f676a6141d
2018-03-23 15:06:22 -07:00
Adam Simpkins
b1e12ca408 fix deadlocks and other synchronization issues in FileInode
Summary:
This replaces the `ensureDataLoaded()`, `materializeForWrite()`, and
`materializeAndTruncate()` methods in `FileInode` with new safer alternatives:
`runWhileDataLoaded()`, `runWhileMaterialized()`, and `truncateAndRun()`

These new methods take a function to run, and run it while holding the state
lock with the FileInode guaranteed to be in the desired state.  They also
require the caller move in the state lock as an argument, to help ensure that
the caller gets the locking behavior correct.

The old methods required that the caller not already hold the state lock while
calling them.  This pre-condition was violated in `FileInode::write()` and
possibly other places.  They also required releasing the lock between they
confirmed the file state and when the caller's function ran, requiring
additional lock and unlock operations, and also making the code harder to
reason about since other threads could change the state during the time when
the lock was released.

Reviewed By: chadaustin

Differential Revision: D7363180

fbshipit-source-id: d8e667d0bc7006c519252a8d0682af97517997eb
2018-03-23 12:36:18 -07:00
David Lai
55c2ef2f6f comment out unused parameters
Summary:
The changes in this diff comments out unused parameters. All changes are automated using clang-tidy.
This will allow us to enable `-Wunused-parameter` as error.

Reviewed By: simpkins

Differential Revision: D7371610

fbshipit-source-id: 0134e2f0b916313d690c073a46d747c52399a226
2018-03-22 15:29:44 -07:00
Adam Simpkins
cece812453 fix a crash in FileInode::read()
Summary:
FileInode::read() did not handle being called in the BLOB_LOADING or NOT_LOADED
states.  This method is only called from EdenFileHandle::read(), which does no
checking that it is fully loaded first.

This fixes read() to always call ensureDataLoaded() first.

Reviewed By: chadaustin

Differential Revision: D7359878

fbshipit-source-id: f5a1c8a28db3267da3180b67f970430e3ea291da
2018-03-21 22:24:19 -07:00
Adam Simpkins
c629b6d508 explicitly delete the InodeBase copy and move constructors
Summary:
While debugging a takeover crash (task #25590050) we wanted to help confirm
that inode objects weren't ever getting copied somehow.  That turned out not to
be the issue, but it still seems worth explicitly deleting the copy and move
constructors and assignment operators for InodeBase.

Reviewed By: wez

Differential Revision: D7342050

fbshipit-source-id: ae07214072bfb8353584a07066aae2dc1adf2797
2018-03-20 17:35:34 -07:00
Adam Simpkins
685077677e update getScmStatusBetweenRevisions() to avoid creating inode objects
Summary:
Update the getScmStatusBetweenRevisions() thrift call to use the new
diffCommits() function that diffs source control Tree objects without creating
TreeInode objects to perform the diff.

This addresses two bugs:
- Each call to EdenMount::diffRevisions() constructed a new root inode
  associated with the mount, and this would never get destroyed.  It was not
  destroyed at the end of the diffRevisions() call since inodes are normally
  not destroyed immediately when they are unreferenced.  It was not destroyed
  during EdenMount::shutdown() since EdenMount didn't have any references to
  these additional root inode structures and their children.
- EdenMount::diffRevisions() incorrectly swapped ADDED and REMOVED statuses in
  the result.

Reviewed By: wez

Differential Revision: D7341609

fbshipit-source-id: 16e755a0ff685f51c977c3b27d6af96908f33494
2018-03-20 16:47:12 -07:00
Adam Simpkins
65a682a1ff add a function for diffing source control commits
Summary:
Add a function for diffing two source control commits without needing to
instantiate TreeInode objects.

Reviewed By: wez

Differential Revision: D7341604

fbshipit-source-id: 557eef87faa2785ab96d51b09569a46f892a71f6
2018-03-20 16:47:12 -07:00
Adam Simpkins
28426f4d29 throw all errno exceptions as std::generic_category
Summary:
Fix the code to generate exceptions based on an errno error using
std::generic_category rather than std::system_category.

Reviewed By: yfeldblum

Differential Revision: D7329997

fbshipit-source-id: 3fe257bbbc7a631c801f31120592c8bdbc25c8bf
2018-03-20 13:38:45 -07:00
Adam Simpkins
a3c582d708 check for std::generic_category when looking for errno errors
Summary:
Add a new utils/SystemError.h header with helper functions to check if a
`std::system_error` contains an errno value.

Most of the code in Eden previously only checked for `std::system_category`
when looking for errno values.  `std::generic_category` is the correct category
to use for errno exceptions, but folly/Exception.h incorrectly throws them as
`std::system_category` today.  This change makes Eden treat either error type
as errno values for now.

Reviewed By: yfeldblum

Differential Revision: D7329999

fbshipit-source-id: 67a3c3ea10371c53a2e34236b7575deac4cbd53a
2018-03-20 13:38:45 -07:00
Adam Simpkins
bfcf4c574a remove the fusell namespace
Summary: Move everything in the `facebook::eden::fusell` namespace to `facebook::eden`

Reviewed By: chadaustin

Differential Revision: D7314458

fbshipit-source-id: db56d3e5fb898235e1376ac76077cf780d9b4698
2018-03-19 17:01:52 -07:00
Adam Simpkins
da3c070d70 rename FileHandle to EdenFileHandle
Summary:
This helps distinguish `facebook::eden::FileHandle` from
`facebook::eden::fusell::FileHandle`, and will make it possible to eliminate
the separate `facebook::eden::fusell` namespace in the future.

Reviewed By: chadaustin

Differential Revision: D7314456

fbshipit-source-id: 0869427766fe666d119a59c7df1c97825a8ad36e
2018-03-19 12:55:17 -07:00
Adam Simpkins
f25e5d4c46 move FileHandleMapTest from inodes/test to fuse/test
Summary:
This test exercises code under eden/fs/fuse, so put it with that directory's
tests.

Reviewed By: chadaustin

Differential Revision: D7314457

fbshipit-source-id: b664aaa3086b2e65f7ae8b76ae71878f39fd9d17
2018-03-19 12:55:17 -07:00
Chad Austin
82d2a71c41 Add a loading bit to TreeInode::Entry
Summary:
There's some code that uses Entry::hasInodeNumber to decide whether an
inode is in the process of being loaded.  This change is a
prerequisite for D7052470.

Reviewed By: simpkins

Differential Revision: D7311182

fbshipit-source-id: e04a89c814950e6ce33e73b963b3ffb0f0e353b8
2018-03-19 11:22:00 -07:00
Adam Simpkins
1c46d4c9e1 have FuseChannel return its FD in the completion future
Summary:
Remove the `FuseChannel::stealFuseDevice()` method, and instead change the
session completion future to return the FUSE device FD if it is still valid.

This ensures we only extract the FUSE device when it is still valid: if an
unmount event is being processed by a FUSE worker thread simultaneously with a
call to `FuseChannel::takeoverStop()` the session completion future will return
an empty `folly::File` since the FUSE device has been shut down.

This also helps clarify the synchronization semantics around modification to
the `fuseDevice_` member variable.

Reviewed By: wez

Differential Revision: D7300847

fbshipit-source-id: 02ced8fc9d24e7cd526d911782949d0bfbf0e5a7
2018-03-16 17:39:13 -07:00
Adam Simpkins
8eff641bf3 prevent FuseChannel from being destroyed with outstanding requests
Summary:
The FuseChannel destructor previously could be invoked while there are still
outstanding requests, which would cause problems when responses were generated
for these requests.

This makes the FuseChannel destructor private, requiring users to always
allocate FuseChannel objects on the heap and destroy them using a destroy()
method.  The destroy() method still blocks waiting for the FUSE worker threads
to exit, but if there are still outstanding FUSE requests it defers the
deletion of the FuseChannel until they are complete.

The EdenMount class currently couldn't ever destroy FuseChannel objects with
outstanding requests, since it waits for the completion future to fire before
invoking the destructor.  Fixing this behavior is mostly for correctness of the
FuseChannel API and for the benefit of our unit tests.

Reviewed By: chadaustin

Differential Revision: D7297829

fbshipit-source-id: 643d1332be84a1f25ee30ba2a2ea3515806f00ef
2018-03-16 12:35:19 -07:00
Adam Simpkins
ac35979de3 move the clock to ServerState
Summary:
Make ServerState also store the clock as a member variable.  This moves more
server-wide state into the ServerState class, and allows us to eliminate
another argument to the EdenMount constructor.

Reviewed By: chadaustin

Differential Revision: D7297832

fbshipit-source-id: 2a063d67752f46686987390b3faefb304455568a
2018-03-16 12:35:19 -07:00
Adam Simpkins
89b0607f0f move the main thread pool to ServerState
Summary:
Move the EdenCPUThreadPool from EdenServer to ServerState.

This ensures that all EdenMount objects always have a thread pool.  Previously
most unit tests were creating an EdenMount without a thread pool set, but the
FileInode code and TreeInode code could end up wanting to use the thread pool
even if no FuseChannel is running.

Reviewed By: chadaustin

Differential Revision: D7297828

fbshipit-source-id: 9861b3439cd091afe31fa13f449aa14656983318
2018-03-16 12:35:19 -07:00
Adam Simpkins
c5f4ea6f8b update FuseChannel::initialize() to return the completion future
Summary:
Remove the `FuseChannel::getSessionCompleteFuture()` method and instead have
`initialize()` and `initializeFromTakeover()` return the `Future` that can be
used to wait on session completion.

This makes it explicit from an API perspective that this session completion
future will only be invoked if initialization is successful.  It also
eliminates the possibility of anyone calling getSessionCompleteFuture() more
than once.

I also changed the session completion future to use a folly::SemiFuture rather
than a folly::Future, to make it explicit that callers generally should not
execute their callback inline in the same thread where the SemiFuture is
fulfilled.

Reviewed By: chadaustin

Differential Revision: D7297835

fbshipit-source-id: 3a1157951f0738f1692833ed5e875c3e9c6d6d69
2018-03-16 12:35:19 -07:00
Chad Austin
a6da2a8fbd add an operator for InodeNumber literals
Summary: Testing convenience.  The NO_CHECK constructor is no longer necessary now that simpkins made the original constructor constexpr.

Reviewed By: simpkins

Differential Revision: D7295539

fbshipit-source-id: 717f5a7a8d3d9790966fad441da7b3308495e2c3
2018-03-15 18:20:29 -07:00
Chad Austin
053bec97ac Eliminate InodeMap::load and require that the takeover state be passed into initialize
Summary: Cleaning up the takeover initialization code for EdenMount and InodeMap.

Reviewed By: simpkins

Differential Revision: D7294419

fbshipit-source-id: 58506f04259bb1017e6cd2e80e40e5820de6200f
2018-03-15 17:48:27 -07:00
Chad Austin
20dc41871b Make it clearer that SerializedInodeMap is a byproduct of takeover shutdown
Summary:
Instead of having a rule that save() must be called after
InodeMap::shutdown, just have InodeMap::shutdown return the
SerializedInodeMap if it's desired.

Reviewed By: simpkins

Differential Revision: D7292773

fbshipit-source-id: 2ba35fc729e19af122fe5d6c5a3287ad6b8af946
2018-03-15 17:48:27 -07:00
Adam Simpkins
fdecf19d91 update FuseChannel to signal the session complete future immediately
Summary:
This changes FuseChannel to fulfill the session complete future immediately in
the thread where it finishes.  This may occur inside a FUSE worker thread.
It is now up to the caller to use `via()` if they want their callback to run in
a separate thread.

This simplifies the FuseChannel code and also addresses a crash that occurs in
the unit tests sometimes: If the FuseChannel destructor is invoked without
explicitly invoking the FuseChannel, it would schedule the session complete
promise to be fulfilled in a separate EventBase thread.  However, the promise
may then have already been destroyed by the time it can run in the EventBase
thread.

There are still additional synchronization issues to fix in the FuseChannel
tests, but this resolves one problem.

Reviewed By: chadaustin

Differential Revision: D7282001

fbshipit-source-id: be64d3ef6a0e664ed7a2cf93a549acc140184095
2018-03-15 13:48:45 -07:00
Adam Simpkins
b37dfd0707 fix handling of empty .gitignore files
Summary:
Empty .gitignore files should be processed normally, and treated as no new
ignore rules.  The logic in D6659654 had accidentally introduced a bug where we
would completely skip processing any directories that contained empty
.gitignore files.

Reviewed By: wez

Differential Revision: D7261276

fbshipit-source-id: 033e199f15d7763bff5f9a080a226c50e481aa9d
2018-03-13 18:30:49 -07:00
Adam Simpkins
fef4a43da7 restructure FuseChannel initialization and synchronization
Summary:
- Update FuseChannel::initializate() to not require an Executor.  Rather than
  performing initialization using the supplied Executor, it simply starts one
  worker thread first and performs initialization there.
- Change the API semantics slightly so that the session complete future is
  invoked only if initialization succeeds.  Previously the session complete
  future could be invoked if initialization failed as well.
- Replace the activeThreads counter with a stoppedThreads counter to determine
  when the session complete future should be invoked.  The previous
  activeThreads behavior was somewhat racy, since the activeThreads counter was
  incremented inside each worker thread, but most places that checked it did
  not wait to ensure that all worker threads had successfully incremented it
  yet.

Reviewed By: chadaustin

Differential Revision: D7243910

fbshipit-source-id: 93b3465509bd9bf6fa90ea097e70dac3193172f9
2018-03-13 13:29:03 -07:00
Chad Austin
7a03509e90 fix opt build
Summary: It's a little surprising to me the clang build passed without these explicit template instantiations!

Reviewed By: simpkins

Differential Revision: D7253536

fbshipit-source-id: 2f48d5571777f4e978b6947183eefb03158d5014
2018-03-12 22:22:59 -07:00
Adam Simpkins
1b441aa0b4 split up FUSE initialization for fresh start vs takeover
Summary:
Split up the FuseChannel and EdenMount APIs for starting a brand new FUSE
channel vs taking over an existing channel.

These operations are somewhat different as initializing a new FUSE channel
requires performing a negotiation with the kernel that will not complete
immediately.  Therefore these APIs return a Future object.  Taking over an
existing FUSE channel is always an immediate operation, and therefor does not
need to return a Future object.

Reviewed By: chadaustin

Differential Revision: D7241997

fbshipit-source-id: 22780f2df76b2d554ab2a4043b6425fa7a4e9c94
2018-03-12 21:28:50 -07:00
Adam Simpkins
81aa1a31a4 make sure we ignore SIGPIPE in unit tests
Summary:
Ensure that we ignore SIGPIPE in unit tests.  The
`FuseChannel::requestSessionExit()` function sends SIGPIPE to its worker
threads, and expects this to wake up the worker threads if they are stuck
inside a read() call.

In normal program builds folly/Subprocess.cpp causes SIGPIPE to be ignored on
startup.  However, Subprocess.cpp is not necessarily linked into all of our
unit tests.  I haven't tracked down exactly why, but SIGPIPE in the unit tests
seems to kill the entire process only in opt-ubsan builds.

In the future we probably should clean up how requestSessionExit() triggers its
worker threads to exit: the current code is still potentially racy, since the
worker threads could receive the SIGPIPE just after checking `sessionFinished_`
and before calling `read()`, in which case they may go back to sleep rather
than exiting.  However for now this should be a simple fix to get the tests
passing in all build modes.

Reviewed By: wez

Differential Revision: D7224370

fbshipit-source-id: a56fe3331fc5aa6a49ccbe6b0678b479a44ffc07
2018-03-12 11:46:20 -07:00
Chad Austin
61d9db7110 reduce newPtrLocked call sites and document why it's safe
Summary:
To make it clearer to me why all the calls to newPtrLocked were safe, and to
eliminate some duplication, I captured the newPtrLocked call patterns into
member functions on LoadedInode and TreeInode::Entry.

Reviewed By: simpkins

Differential Revision: D7207542

fbshipit-source-id: 25de77e72c0898be43b3fbdddab835d64101755e
2018-03-09 13:37:08 -08:00
Chad Austin
8fbe2f85fa add explicit conversion from std::unique_ptr to InodePtr
Summary:
To make it clearer why newPtrLocked is safe during the Inode class
construction process, add a takeOwnership function (better name
suggestions welcome) that converts from the newly-instantiated
unique_ptr to a managed InodePtr.

Reviewed By: simpkins

Differential Revision: D7204818

fbshipit-source-id: 8a40189588442490120623da86195c6fc99c9c51
2018-03-09 13:37:08 -08:00
Chad Austin
089a30db13 allow constructing an entry with an inode number
Summary:
This diff is mostly preparation. It's submitted separately to
remove mechanical refactoring noise from the following diff, where
every entry is assigned an inode number upon construction.

Reviewed By: simpkins

Differential Revision: D7116832

fbshipit-source-id: 2943c45340a9a751eb52bf13e19d233d829494c0
2018-03-07 23:11:49 -08:00
Chad Austin
ab39bcc10f decouple inode allocation initialization from the rest of InodeMap
Summary:
If the root TreeInode wants to allocate inode numbers, the inode
allocator must be initialized first.  But complete InodeMap
initialization requires the root TreeInode.  So split this into two
parts.

Also, I changed the inode allocator to a single atomic increment instead
of a lock acquisiton.

Finally, the extra assertions in this diff uncovered what looks like a
bug in the takeover logic where nextInodeNumber_ could end up being
smaller than the value in the takeover data, since the max inode
number from the overlay was assigned after loading from takeover data.

Reviewed By: simpkins

Differential Revision: D7107706

fbshipit-source-id: ec43cc81c11d709261598739c622609b372433a2
2018-03-07 23:11:49 -08:00
Chad Austin
857d17f82d assert if allocateInodeNumber is called prior to InodeMap::initialize
Summary:
I spent way too long trying to figure out why my refactorings were
causing invariant errors inside InodeMap.  It turns out that we
initialize the root TreeInode before InodeMap::initialize is called,
which I suspect resulted in duplicate inode numbers being handed out.

Reviewed By: simpkins

Differential Revision: D7106302

fbshipit-source-id: b459734fb96bfbb6b4b27a1d23de8b6406d30ca4
2018-03-01 12:28:00 -08:00
Chad Austin
6e1782fc6d simplify opendir a bit
Summary: One fewer unnecessary Future.

Reviewed By: simpkins

Differential Revision: D7104938

fbshipit-source-id: bc6967ce4ae5b7c7ff45d028155306e41d810bdf
2018-03-01 12:28:00 -08:00
Adam Simpkins
d5e3d5dd63 add initial test code for FUSE channel communication
Summary:
This adds a FakeFuse class to simulate a FUSE connection to the kernel, but
that is actually communicating with our userspace test harness code.  This also
adds a FakePrivHelper class which implements the PrivHelper interface but
returns FakeFuse connections rather than real FUSE connections to the kernel.

This will enable us to write unit tests that exercise more of the FUSE and
EdenMount logic, and will also enable us to test error conditions and ordering
behaviors that are difficult to reliably reproduce with a real FUSE mount.

This also includes some very basic tests using this new code.  The code in
fuse/test/FuseChannelTest.cpp creates a FuseChannel using a FakeFuse object,
and the code in inodes/test/FuseTest.cpp creates a full EdenMount object using
FakePrivHelper and FakeFuse.  The tests are pretty similar for now, and only
exercise the FUSE initialization code.  I will expand these tests in subsequent
diffs.

Reviewed By: wez

Differential Revision: D7050826

fbshipit-source-id: 4f82375d65664ca3a5a228a577caa4d1d47454fe
2018-02-27 22:57:09 -08:00
Chad Austin
34f78baa21 make it annoying to use InodeNumber as an integer
Summary:
I'm seeing test failures that I have not yet understood and I
thought they might be caused by an implicit conversion from
fusell::InodeNumber to bool.  Well, they're not, but this is how I
discovered that.  I'm not sure I want to land this change, but I'm
going to leave it around until I figure out what's happening with my
other diffs.

Reviewed By: simpkins

Differential Revision: D7077635

fbshipit-source-id: 50bf67026d2d0da0220c4709e3db24d841960f4b
2018-02-27 12:44:41 -08:00
Chad Austin
690bdf3c1b simplify child loading codepaths
Summary:
I am working on a stack of diffs that changes how we allocate inode
numbers to tree entries.  I was hitting test failures I could not
understand, so in the process of trying to understand the flows
through InodeMap, I found newChildLoadStarted to be redundant with
shouldLoadChild.

Note: Today, allocateInodeNumber() acquires the InodeMap's lock, but
in a later diff, inode numbers will be assigned en masse during
TreeInode construction.

Reviewed By: simpkins

Differential Revision: D7059719

fbshipit-source-id: 624b861040d585d2cae41d7ec2aae7d528ff8336
2018-02-27 12:44:41 -08:00
Adam Simpkins
bf33c996c6 allow FUSE caching of negative lookup() responses
Summary:
Previously we returned an ENOENT error in response to a FUSE lookup() call for
a name that does not exist.  However, this does not allow FUSE to cache the
result, so we will continue to receive lookup() calls for this path in the
future.

This changes EdenDispatcher to return a successful response with an inode
number of 0 instead.  This tells the kernel that the name does not exist, but
allows the kernel to cache this negative lookup result (for as long as
specified in the entry_valid field in the response).

Reviewed By: wez

Differential Revision: D7076811

fbshipit-source-id: a2b9977e58d6b6eecb584699b9d93b5ad29ad5ad
2018-02-26 19:50:47 -08:00
Adam Simpkins
ddc731759d invalidate the FUSE entry cache when creating new child entries
Summary:
Update the TreeInode code to always update the FUSE cache whenever we add a new
entry to the directory.

Up to now we have been fine without this since the kernel never cached negative
lookup responses for us.  In order to turn on FUSE caching of negative lookup()
responses we need to invalidate the cache whenever we create a new entry.

- Have create(), symlink(), mknod() and mkdir() invalidate the FUSE entry cache
  if they are not being invoked from a FUSE request.  These are almost always
  invoked from a FUSE request, but flushing the cache is the correct thing to
  do if we add code in the future that can trigger these from a thrift call or
  via some other non-FUSE code path.

- Change the checkout code to invalidate the FUSE cache whenever it creates new
  children entries.

Reviewed By: wez

Differential Revision: D7076812

fbshipit-source-id: d6489995b415260e84b3701c49713b0ef514f85d
2018-02-26 19:50:47 -08:00
Igor Sugak
2f718d73b2 Back out "[codemod] - comment out unused parameters"
Reviewed By: igorsugak

fbshipit-source-id: 4a93675cc1931089ddd574cacdb15d228b1e5f37
2018-02-22 12:42:29 -08:00
David Lai
f2975583d8 - comment out unused parameters
Reviewed By: everiq, igorsugak

Differential Revision: D7046710

fbshipit-source-id: 8e10b1f1e2aecebbfb229c742e214db887e5a461
2018-02-22 09:51:57 -08:00
Adam Simpkins
21d2b6c46d Remove TARGETS files
Summary:
This removes the TARGETS files from the eden github repository.  The
open source buck build has been failing for several months, since buck
removed support for the thrift_library() rule.

I will potentially take a stab at adding CMake build support for Eden
at some point in the future.

Reviewed By: chadaustin

Differential Revision: D6893233

fbshipit-source-id: e6023094a807cf481ac49998c6f21b213be6c288
2018-02-20 19:57:45 -08:00
Chad Austin
bb302aac4b simplify isSameAs checking of mode bits
Summary: Per code review comments on D6983198, this simplifies the way we check if mode bits have changed in a meaningful-to-source-control way.

Reviewed By: simpkins

Differential Revision: D7015339

fbshipit-source-id: 548ead337fbea1c1dcb72b880921671e9b6188ac
2018-02-20 11:36:11 -08:00
Chad Austin
7d0b2433cf make modeFromTreeEntryType a free function
Summary:
mode_t isn't really part of a TreeEntry and I also wanted to see all
the places where we convert an entry type from source control into
mode bits.

Reviewed By: simpkins

Differential Revision: D6983198

fbshipit-source-id: ce1d0976f5fc5130c34a8c93c07a4e26a7cdaf71
2018-02-16 15:57:39 -08:00
Chad Austin
622a5ecbc2 rename FileType to TreeEntryType
Summary:
This is the type of a tree entry, which may be another tree, so
FileType is not an accurate name.

Reviewed By: simpkins

Differential Revision: D6981168

fbshipit-source-id: 997eb8a27f599310ed678ce221c8083722db8bff
2018-02-16 15:57:39 -08:00
Chad Austin
2ead6a1148 store timestamps in memory with 64-bit EdenTimestamp
Summary: Actually use EdenTimestamp instead of timespec to represent InodeTimestamps.

Reviewed By: simpkins

Differential Revision: D6990645

fbshipit-source-id: d77996e10c175959bb367ecb2e3d79ca10b669ff
2018-02-15 16:31:43 -08:00
Chad Austin
b99d81654a introduce an EdenTimestamp type
Summary:
While we're changing how timestamps are stored, we might as well
implement this small-ish efficiency.  Instead of storing timestamps as
a timespec (16 bytes), store them as 64-bit nanoseconds with a range
slightly larger than what ext4 supports.  Assuming a million inodes,
this saves 24 MB.

This diff introduces the EdenTimestamp type.  The next diff will start
using it.

Reviewed By: simpkins

Differential Revision: D6957659

fbshipit-source-id: 4551af6f5b8c1ff610ba88795f69e7d69d7f605d
2018-02-15 16:31:42 -08:00
Chad Austin
8c44274053 replace TreeEntryType with TreeEntry::isTree
Summary:
I want to rename FileType to TreeEntryType so I removed this one first
and replaced all of its uses with an isTree() method.

Reviewed By: simpkins

Differential Revision: D6980501

fbshipit-source-id: 105b8c599585e63efd44043e761db40e2824e77e
2018-02-15 14:46:33 -08:00
Chad Austin
895a0196d9 compute permission bits based on FileType in TreeEntry
Summary:
Our Model TreeEntry code was a bit too general - in reality, both git
and hg only support a handful of specific tree entries: regular files,
executable files, symlinks, and trees.  (git also supports
submodules.)  This diff delays the expansion of a TreeEntry's type
into a full mode_t.

Reviewed By: simpkins

Differential Revision: D6980003

fbshipit-source-id: 73729208000668078a180b728d7e0bb9169c6f3c
2018-02-15 14:46:33 -08:00
Chad Austin
c366a48e24 Entry::isDir is redundant with isDirectory
Summary: I should have caught this before...

Reviewed By: wez

Differential Revision: D6995395

fbshipit-source-id: 08efd0aacb051f2b1754930b311e3a42afc3c538
2018-02-14 22:26:00 -08:00
Chad Austin
8f77f03df3 take Dir& instead of Dir* in saveOverlayDir
Summary:
Another small refactoring that I don't want mixed into my
bigger diffs.

Reviewed By: wez

Differential Revision: D6927482

fbshipit-source-id: 28cc60dfdffb50921a5ef9cca4e2814b90d3b701
2018-02-14 18:08:49 -08:00
Chad Austin
191e86aece eliminate some mode_t uses
Summary:
There were places we were acquiring a lock unnecessarily.  In
addition, I'm looking at reducing the number of places where we store
the full mode_t to see if we can get away with dirtype_t or something
similar.

Reviewed By: wez

Differential Revision: D6972140

fbshipit-source-id: bb29a4473f3056e39596600d22e67374ca484735
2018-02-12 17:55:57 -08:00
Adam Simpkins
58fa81ebf2 report a reasonable value in stat.st_blocks for files
Summary:
Update FileInode so that getattr() and setattr() both return a reasonable value
in st_blocks.

Previously we always returned 0 in st_blocks, which caused applications like
`du` to always report files as using 0 space in Eden mounts.  Now we compute
st_blocks based on st_size, so that `du` will report reasonable estimates for
when scanning the size of subdirectories inside an Eden mount.

Reviewed By: chadaustin

Differential Revision: D6932098

fbshipit-source-id: bd29e46821176e510f420e6e2b6ce480b80d50ff
2018-02-08 19:36:03 -08:00
Adam Simpkins
fe1c35f781 move the privhelper APIs into a PrivHelper class
Summary:
Move all of the privhelper functionality into a PrivHelper class.  The
ServerState object now stores the PrivHelper object to use, rather than having
a global singleton.

This will make it easier to stub out the PrivHelper functionality during unit
tests.

Reviewed By: wez

Differential Revision: D6929862

fbshipit-source-id: e3edcb0a03ba9afdf34554cb961fd74557cdd6e3
2018-02-08 19:36:03 -08:00
Adam Simpkins
bc93fd13b6 update diff code to use previously retrieved UserInfo
Summary:
Update EdenMount::diff() to use the UserInfo object stored in the shared
ServerState rather than calling UserInfo::lookup() on each diff operation.

Reviewed By: wez

Differential Revision: D6929865

fbshipit-source-id: a68ab1fa9eb345b59972e67c3aac258b4dbcdab5
2018-02-08 19:36:03 -08:00
Adam Simpkins
265b17d188 add a new ServerState class to store process-wide state
Summary:
Add a new ServerState class to store process-wide state that is shared across
multiple mounts.  Up until now we have passed around the shared state data as
separate variables.

This is intentionally separate from the existing EdenServer class to allow unit
tests to create EdenMount objects without an EdenServer object.

Reviewed By: wez

Differential Revision: D6929861

fbshipit-source-id: 5f22efb6d79dfd70031be1dc37f494c2ad8af902
2018-02-08 16:43:22 -08:00
Wez Furlong
2e660e0d45 remove FuseChannel::threadsStoppingFuture
Summary:
We no longer need this and I believe that this was contributing
to this source of flakiness in our CI; this stack trace triggers when
we get an aborted or short read from the kernel:

```
*** Aborted at 1517827659 (Unix time, try 'date -d 1517827659') ***
*** Signal 11 (SIGSEGV) (0x2d0) received by PID 153706 (pthread TID 0x7f63ea37d700) (linux TID 160573) (maybe from PID 720, UID 0) (code: address not mapped to object), stack trace: ***
    @ 0000000002abfa2d folly::symbolizer::(anonymous namespace)::signalHandler(int, siginfo_t*, void*)
                       ./folly/experimental/symbolizer/SignalHandler.cpp:413
    @ 00007f646e96dacf (unknown)
    @ 00007f646e96aa20 __pthread_kill
    @ 0000000001873748 facebook::eden::fusell::FuseChannel::requestSessionExit()
                       ./eden/fs/fuse/FuseChannel.cpp:483
    @ 000000000187d2f7 facebook::eden::fusell::FuseChannel::processSession()
                       ./eden/fs/fuse/FuseChannel.cpp:656
    @ 000000000187dab9 facebook::eden::fusell::FuseChannel::fuseWorkerThread(unsigned long)
                       ./eden/fs/fuse/FuseChannel.cpp:493
    @ 00007f646f267170 execute_native_thread_routine
    @ 00007f646e9637a8 start_thread
    @ 00007f646e047a7c __clone
```

my theory is that we're allowing shutdownImpl to free things out from under other
threads before they've all seen this signal and wound down fully.  This is slightly
speculative in that I haven't managed to reproduce this stack trace on my devserver.

We don't really need this additional signal any longer.

Reviewed By: simpkins

Differential Revision: D6907734

fbshipit-source-id: 0f0138b631a7201fc9a4a1c93c2cde846e869cbd
2018-02-07 17:36:11 -08:00
Chad Austin
0783ffe211 pass InodeTimestamps straight to createHeader
Summary: Small refactoring I should have done with the previous diff.

Reviewed By: simpkins

Differential Revision: D6927152

fbshipit-source-id: 1dcda01134c3d63c62169c5728dba24ca0eebd68
2018-02-07 15:17:51 -08:00
Adam Simpkins
d900cc70ff short circuit diff operations for non-materialized trees
Summary:
Update `TreeInode::diff()` to check if its hash matches the source control tree
it is being compared to, and return early if they are identical.

I'm surprised that I forgot to include this initially when implementing
`TreeInode::diff()`

This makes `hg status` faster when a large number of unmodified directories
have been loaded.

Reviewed By: chadaustin

Differential Revision: D6890615

fbshipit-source-id: 561630d0220b4875dbf3678161cdb41a8aa4fc82
2018-02-05 16:08:09 -08:00
Adam Simpkins
e2c1034d26 slight refactoring of TreeInode::diff()
Summary:
This re-orders some of the code in `TreeInode::diff()` slightly.  This should
not affect the behavior of the code.

This moves the `isIgnored` check inside the main `contents_.wlock()` block.
This reduces the number of places where we grab the lock, and will help keep
things simple for an upcoming diff where I need to add some more checks in this
code with the lock held.

This also changes `inodeFuture` to use the new `Future::makeEmpty()`
constructor rather than having to use an `Optional<Future>`

Reviewed By: chadaustin

Differential Revision: D6890616

fbshipit-source-id: 354bbf6a6be6d356fd23e6c0fb6b534679bbe0bb
2018-02-05 16:08:09 -08:00
Chad Austin
8801f19064 convenience constructors for InodeTimestamps
Summary: Small things I've needed in later diffs.

Reviewed By: wez

Differential Revision: D6877755

fbshipit-source-id: c9002eb0b92dbd8fe9c4f636d2ca79b25cde331f
2018-02-01 16:24:37 -08:00
Chad Austin
20f7a10bfd split InodeTimestamps into its own file
Summary:
While working on timestamp storage, the fact that
InodeTimestamps was a member of InodeBase kept getting in the way.
Make it its own type.

Reviewed By: simpkins

Differential Revision: D6862835

fbshipit-source-id: 91d8984764f0586b9fa52e961eb5606a530e0416
2018-02-01 12:34:15 -08:00
Adam Simpkins
00a232d868 make Clock::getRealtime() const
Summary: This API seems like it should be const, as it does not modify the clock.

Reviewed By: chadaustin, zhupanov

Differential Revision: D6869719

fbshipit-source-id: c8bf4ccab34538b59e6baeedd0b0ff88b328236e
2018-02-01 11:19:15 -08:00
Wez Furlong
89c0c2cb90 clean up fuse init processing
Summary:
This diff moves the mount-time initialization handling
out of the main loop.  This rationale for this is:

* We don't (and shouldn't!) need to process FUSE_INIT for takeover
  processing, and this structure allows us to make stronger assertions
  about our state.
* we can avoid spinning up multiple threads in the (rare!) case that
  the FUSE_INIT fails
* It is now a little harder for exceptions during initialization to
  escape our notice.

In rearranging this stuff, I found a race condition in the worker thread
shutdown; we could erroneously emit a completion event before all of
the threads had been torn down and this resulted in sporadic integration
test failures hitting the assertion for the number of joined threads
in the destructor.

Reviewed By: simpkins

Differential Revision: D6766330

fbshipit-source-id: 32afb5a7c739c75aebfdb0a8f896eec5f41ad33f
2018-01-31 15:08:42 -08:00
Chad Austin
d0823ab865 unbox Dir Entries
Summary:
Dir's contents were represented as a vector of 64-bit
pointers to 48-byte structs.  This change removes that layer of
indirection, reducing memory usage and slightly pessimizing insertion.

The diff is mostly mechanical outside of the TreeInode.h changes and
calls to emplace..

I'll run memory tests tomorrow, though it's a gamble as to whether
private bytes will show a difference.  I may need to shrink the Entry
struct too.

Reviewed By: wez

Differential Revision: D6804957

fbshipit-source-id: b126656dbc7951565e74b6401adde6353e809056
2018-01-30 15:11:55 -08:00
Chad Austin
a06f12e6b0 avoid a strlen in DirHandle
Summary:
Tiny thing I noticed when reading code.  Keep the entry name
as a StringPiece rather than bouncing through char*.

Reviewed By: zhupanov

Differential Revision: D6820080

fbshipit-source-id: 884e55f74094f44012efbe44b86d8e5903300967
2018-01-30 13:35:49 -08:00
Chad Austin
144a47d1ae fix status/diff when symlinks change
Summary:
isSameAs calls getSha1 which was failing on symlinks.  The
original concern was that asking for the SHA-1 of a symlink is
ambiguous: do you want the hash of the symlink or the target?  But we
already check for whether you are requesting the SHA-1 of a symlink in
EdenServiceHandler, so it's redundant and incorrect to check in
FileInode too.

Reviewed By: simpkins

Differential Revision: D6847489

fbshipit-source-id: 13966da06bcde75c5c568e09fef14e735de47cfb
2018-01-30 13:35:49 -08:00
Chad Austin
697eb8a6fd run clang-format across eden
Summary:
```
find . \( -iname '*.cpp' -o -iname '*.h' \) -exec arc lint --apply-patches {} +
```

Differential Revision: D6820436

fbshipit-source-id: 173c0e3b5c023c1c9276f34e17d732f1dd161892
2018-01-26 11:20:31 -08:00
Chad Austin
8219f5c60a have eden stats show file and tree counts
Summary:
It's interesting to see the total number of loaded files
vs. trees when the loaded inode count is high.

Reviewed By: wez

Differential Revision: D6765874

fbshipit-source-id: 178b30184428bd5cf5e005eb475e4f5a1476c385
2018-01-24 15:29:16 -08:00
Chad Austin
adce4eba1e fix determining which inodes can be unloaded
Summary:
I'm not sure what was wrong with the old code, but I
simplified and clarified all of the time math and now `eden debug
unload` behaves as I'd expect it should.

Reviewed By: simpkins

Differential Revision: D6764962

fbshipit-source-id: 3ed359d4ab4652e95d1538a0982c24185999351c
2018-01-24 15:29:16 -08:00
Chad Austin
c0acea995d remove rdev from state and don't pretend we support it for now
Summary:
rdev doesn't add any value yet. We can add it back if we want
to implement support.

Reviewed By: simpkins

Differential Revision: D6792346

fbshipit-source-id: ce16317074f1daa456737c55804da8fb7f2b7a94
2018-01-24 13:36:05 -08:00
Wez Furlong
056d7f4917 slightly simplify FuseChannel initialization
Summary:
This slightly improves the code in EdenMount by having
just a single call to the FuseChannel constructor with an optional
`fuse_init_out` instance that we can use to determine if we are
performing a takeover or not.

Reviewed By: simpkins

Differential Revision: D6766328

fbshipit-source-id: ece140a1572e2934a3e35bfe25b83af910346c18
2018-01-24 11:34:48 -08:00
Sergey Zhupanov
ae0f9c1aa6 Minor stylistic changes.
Summary: Minor stylistic changes that were done during constification but factored out.

Reviewed By: chadaustin

Differential Revision: D6774976

fbshipit-source-id: d18cd339153cf16ff69be0de5f3eb019a4baa1a0
2018-01-23 14:52:34 -08:00
Sergey Zhupanov
25e74d5712 Fixing opt build lint warning introduced by a previously landed revision.
Summary: Added folly::assume_unreachable() to quell the false positive warning.

Reviewed By: wez

Differential Revision: D6787186

fbshipit-source-id: 400695f8cda915557cf4999b1b998a5aefc558f0
2018-01-23 11:49:11 -08:00
Sergey Zhupanov
a7a0eb430d Refactor if processing of enum class as switch for safety and compile time support
Summary:
The value we get is of enum class, so it is guaranteed to be in the valid set.
Omitting default we get compiler support if we ever expand the set of values.
Throw becomes obviated, because it becomes unreachable.

Reviewed By: simpkins

Differential Revision: D6771224

fbshipit-source-id: 039f0545d20649193b3fb74981ee7f027f31fd8e
2018-01-22 20:07:32 -08:00
Sergey Zhupanov
5f98c49a19 Stop ignoring errors in dir creation in EdenMount::performBindMounts()
Summary: Switch from error-code-based to exception-based boost call to ensure errors are caught.

Reviewed By: simpkins

Differential Revision: D6771193

fbshipit-source-id: 592867c097c2af580f5b992b01e2c1b6c4a12ca4
2018-01-22 17:55:24 -08:00
Sergey Zhupanov
7c1dac9a29 Replaced unnecessary memset calls with C++11 struct = {} init syntax.
Summary: Replaced memset used to 0-init structs with POD fields with = {} init.

Reviewed By: simpkins

Differential Revision: D6770868

fbshipit-source-id: 190205a277e3c73711813bc515b860b107d41f83
2018-01-22 17:55:24 -08:00
Wez Furlong
0cd02dc285 move InodeMap serialization to new takeover.thrift file
Summary:
This is moving some files around in preparation for
moving TakeoverData to using thrift for its serialization

Reviewed By: simpkins

Differential Revision: D6733405

fbshipit-source-id: 235ba237546f8ef606de8445db45683ce38a2d2c
2018-01-17 11:51:30 -08:00
Wez Furlong
ca3a259bdc allow loading unlinked inodes
Summary:
This implements a TODO/FATAL that is important for
graceful restarts to be useful in my "acid test" scenario,
which is to perform a graceful restart while buck build is
running.

Reviewed By: simpkins

Differential Revision: D6700189

fbshipit-source-id: dec1b818ebc9e907841bc127ee08c953b59d6487
2018-01-12 12:35:35 -08:00
Wez Furlong
530346887d split EdenMount::{create,initialize} -> safer takeover mounting
Summary:
Previously, `EdenMount::create` would implicitly call
`EdenMount::initialize` which would load the root inode and the `.eden` magical
directory.  That's fine for the fresh mount case, but in the case of the
graceful restart we need to take the opportunity to apply the `InodeMap`
from the old process before we start muddying its state.

This diff breaks out the `initialize` method from the `create` method and
makes the mount code call it after potentially loading the `InodeMap` from
the takeover data.

In addition, this diff removes the the `root->loadMaterializedChildren()`
call from the mount initialization code.  It is no longer required to do
this eagerly and it makes things simpler and our memory profile a little
smaller to defer this (I haven't measured how much that impacts things).

Reviewed By: simpkins

Differential Revision: D6691182

fbshipit-source-id: 52033a6d64105b658314a919f69dbfcd4eea242b
2018-01-10 13:13:50 -08:00
Wez Furlong
014789b4ca open file handles now survive graceful restart
Summary:
I'm so-so on a bit of the implementation here, but it works!

I had to change the `takeoverPromise` from the `pair<fuseDevice, connInfo>`
to a new helper struct because we now have three distinct pieces of data
to pass out of EdenMount to build up the overall TakeoverData.

The key change in this diff is that we have to release all of the file handles
we're maintaining in the `FileHandleMap` prior to shutting down the `InodeMap`,
otherwise the `InodeMap` will never complete (it waits for all inodes to be
unreferenced, and that cannot happen while there are open file handles).  I've
made the `FileHandleMap` serialization and clearing contingent on performing a
takeover shutdown because that feels like the safest thing to do wrt. not
losing any pending writes.

Reviewed By: simpkins

Differential Revision: D6672437

fbshipit-source-id: 7b1f0f8e7ff09dbed850c7737383ecdf1e5ff0c7
2018-01-09 22:23:11 -08:00
Wez Furlong
490e6adcf5 inform PrivHelper of takeover; graceful restarts now work!
Summary:
This is the key portion that makes the graceful restart
function.  This diff connects almost all of the moving pieces together;
it informs the priv helper about the takeover mount and transfers
the InodeMap information into the new generation of the eden server.

It doesn't yet load the fileHandleMap (will tackle that in a follow up diff)

Reviewed By: simpkins

Differential Revision: D6670903

fbshipit-source-id: 1770d99eb1477440a6c1deed83b0da55b9c1bbe4
2018-01-09 22:23:10 -08:00
Wez Furlong
ef214c6c4f serialize the InodeMap
Summary:
this isn't how we really want to do this long term, it's
just the most expedient short term implementation.

This diff provides an implementation of the `InodeMap::save()` which
was previously a stub method; the new implementation returns a thrift
structure that encompasses the unloaded inodes in the map, and adds
a corresponding load() method that performs the reverse transformation.

The struct is serialized into the Takeover data.

This diff doesn't hook up the real serialized data to EdenServer; that will happen
in a follow-on diff.

The way that we actually want to handle this longer term is to store the
`numFuseReferences` field into the overlay file on disk, but to do so we
will need to add a mountGeneration field alongside it and ensure that we
always write out the correct information at the correct times.  In addition,
we'd need to add equivalent data to TreeInode::Entry and add accessors that
safely return the correct values in the correct situations.

In the interest of getting something working, I've just dumped this code in
here.

I've also placed the thrift structure for this in `fuse/handlemap.thrift`;
this is a slight layering violation but one that feels "OK" in light of
the imminent refactor of the Takeover data struct to be its own thrift
struct anyway.

Reviewed By: simpkins

Differential Revision: D6670904

fbshipit-source-id: 11a0918954c741935c587e46fcb0e38849010de1
2018-01-09 22:23:10 -08:00
Wez Furlong
8689b37221 connect the fuse device information to the takeover data
Summary:
This adds some plumbing to thread the fuse device descriptor and
negotiated capabilities through to the takeover code.

I initially wanted to just make the
unmount future yield the device descriptor, but since that uses
`SharedPromise` it is not compatible with a move-only type like
`folly:File`, so I added an optional promise to deal with just that.

I'm also populating the takeover mount information (path, bind mounts)
for each mount point.

Reviewed By: simpkins

Differential Revision: D6494509

fbshipit-source-id: a90684292dc1d8e06ce2c0721eadd8d393377f33
2018-01-09 22:23:04 -08:00
Andrew Gallagher
ebab5e09b9 Run autodeps on stale opt-in TARGETS
Reviewed By: luciang, meyering

Differential Revision: D6685618

fbshipit-source-id: 9e0e01a8cbc47f00225fd8445dcc4c35b4e43ffb
2018-01-09 15:12:08 -08:00
Chad Austin
453f3aa507 fix typo in comment
Summary: A prior shelve contained this fix but never got landed.

Reviewed By: wez

Differential Revision: D6676206

fbshipit-source-id: b8c733be663ff56e1a0625f09ec505891d430084
2018-01-08 11:51:29 -08:00
Sergey Zhupanov
0d6c3a31cd Changed TreeInode::loadGitIgnoreThenDiff() to properly handle symlinks to gitignore.
Summary: Added TreeInode::loadGitIgnoreThenDiff() symlink handling with tests.

Reviewed By: simpkins

Differential Revision: D6659654

fbshipit-source-id: 293c913ea56b5b770a051efd78e1e57497c360bd
2018-01-05 15:51:04 -08:00
Sergey Zhupanov
a3ef94a011 Added EdenMount::resolveSymlink(InodePtr pInode) with tests.
Summary: EdenMount::resolveSymlink(InodePtr pInode) resolves symlink to INodePtr.

Reviewed By: simpkins

Differential Revision: D6659644

fbshipit-source-id: 8be9ca06b08bf9730ff961e55c3ee747d5f45707
2018-01-05 15:35:42 -08:00
Wez Furlong
a7d7ae92d3 InodeBase::incFuseRefcount allows arbitrary count
Summary:
We'll need a way to twiddle the refcount by more than
increment at a time for graceful restart.  This mirrors the
same pattern we use to forget() by an arbitrary number.

Reviewed By: chadaustin

Differential Revision: D6668809

fbshipit-source-id: 6e5dc33b5e40f98f01293c89152bfe1e0879f572
2018-01-05 14:22:22 -08:00
Wez Furlong
15c7604d06 remove unused thrift struct
Summary: We forgot to remove this when we moved to be fully inode based in the overlay

Reviewed By: chadaustin

Differential Revision: D6668810

fbshipit-source-id: b79af85a4bbbcefd9227ad69bb8d57b5274cdaed
2018-01-05 14:22:20 -08:00
Chad Austin
0f0b0b6b4d remove unnecessary code and a faulty assertion
Summary:
It is no longer correct to assert that state->file is set if O_TRUNC happened
before blob import from hg finished.  It surprises me we never saw a crash
because of that.  Also, the O_TRUNC path after blob import finishes can never
complete a future, so don't try.

Reviewed By: wez

Differential Revision: D6656699

fbshipit-source-id: 5e245fc46185714e5f5d81c2680835a3497747ff
2018-01-03 17:38:48 -08:00
Chad Austin
5f5b317e8b release blob memory when last file handle is closed
Summary:
Today, if a file is ever opened for read, each FileInode keeps a copy
of the data as long as the FileInode is around.  This results in
excessive memory consumption under common mistakes like repo-wide grep
or `hg revert .`.

I will audit all of the state machine transitions and blob accesses
before landing this diff.

Reviewed By: wez

Differential Revision: D6598957

fbshipit-source-id: 1eb4aeb08057ce993a29a86d298e153675fee4a1
2018-01-03 17:38:48 -08:00
Chad Austin
36a51e8ac6 make readIntoBuffer private
Summary:
This came up when I was auditing the rules about when it's
safe to read from a FileInode. read() must only be called while openCount > 0.

Reviewed By: wez

Differential Revision: D6604898

fbshipit-source-id: 829ddc335bd58201c2b456ee544cdc6253ebf66c
2018-01-03 17:38:48 -08:00
Chad Austin
3b2e9b92ca have ensureDataLoaded() return a FileHandle
Summary:
In a follow-on diff, the constraint will be that state->blob
will only be guaranteed valid after ensureDataLoaded() while a
FileHandle is alive.  Thus, ensureDataLoaded() must return a
FileHandle.

Reviewed By: wez

Differential Revision: D6586237

fbshipit-source-id: ccc269d322b8c725c93145df5de2add9a2b90207
2018-01-03 17:38:48 -08:00
Sergey Zhupanov
29c2999a65 Removed all folly::fbstring uses from eden.
Summary: Removed all folly::fbstring uses from eden.

Reviewed By: wez

Differential Revision: D6597696

fbshipit-source-id: 816ea91fad063eccf9e6a46bf5c5e32bc69c6bf7
2018-01-03 16:41:34 -08:00
Wez Furlong
f51bbd5843 satisfy shadow-compatible-local error
Summary: This is annoying because it isn't actually shadowing and because this isn't picked up in our default mode mode, or in sandcastle.

Reviewed By: chadaustin

Differential Revision: D6656548

fbshipit-source-id: e624cb563d6396c1ab6b93eae14651c16a8c0cd3
2018-01-03 11:06:13 -08:00
Wez Furlong
482d1a1aff move fuse thread pool to FuseChannel
Summary:
Now that we have full control over the fuse session,
moving the threads here makes a lot of sense and makes things
easier from an overall state management perspective.

FuseChannel now provides a future that make it easier for EdenMount to wait
until all the threads and outstanding requests have completed.

There is also a future to determine when the first of the threads
has exited which is used to detect an error condition.  We could
go a bit further with this and have the error condition propagate
out from our dispatcher, but that's a bit further away from my
goal of making the graceful restart stuff work.

I've removed the request counting stuff from Dispatcher as we
can now use the definitive signals from FuseChannel in its place.

Reviewed By: chadaustin

Differential Revision: D6580247

fbshipit-source-id: 6bcc3b8b531d59a3fdd0ca6fd09410ad64f8221a
2018-01-03 09:38:34 -08:00
Wez Furlong
6ff492d11c remove dep on libfuse
Summary:
This serves a few purposes:

1. We can avoid some conditional code inside eden if we know that
   we have a specific fuse_kernel.h header implementation.
2. We don't have to figure out a way to propagate the kernel
   capabilities through the graceful restart process.
3. libfuse3 removed the channel/session hooks that we've been
   using thus far to interject ourselves for mounting and
   graceful restarting, so we were already effectively the
   walking dead here.
4. We're now able to take advtange of the latest aspects of
   the fuse kernel interface without being tied to the implementation
   of libfuse2 or libfuse3.  We're interested in the readdirplus
   functionality and will look at enabling that in a future diff.

This may make some things slightly harder for the more immediate
macOS port but I belive that we're in a much better place overall.

This diff is relatively mechanical and sadly is (unavoidably) large.

The main aspects of this diff are:

1. The `fuse_ino_t` type was provided by libfuse so we needed to
   replace it with our own definition.  This has decent penetration
   throughout the codebase.
2. The confusing `fuse_file_info` type that was multi-purpose and
   had fields that were sometimes *in* parameters and sometimes *out*
   parameters has been removed and replaced with a simpler *flags*
   parameter that corresponds to the `open(2)` flags parameter.
   The *out* portions are subsumed by existing file handle metadata
   methods.
3. The fuse parameters returned from variations of the `LOOKUP` opcode
   now return the fuse kernel type for this directly.  I suspect
   that we may need to introduce a compatibility type when we revisit
   the macOS port, but this at least makes this diff slightly simpler.
   You'll notice that some field and symbol name prefixes vary as
   a result of this.
4. Similarly for `setattr`, libfuse separated the kernel data into
   two parameters that were a little awkward to use; we're now just
   passing the kernel data through and this, IMO, makes the interface
   slightly more understandable.
5. The bulk of the code from `Dispatcher.cpp` that shimmed the
   libfuse callbacks into the C++ virtual methods has been removed
   and replaced by a `switch` statement based dispatcher in
   `FuseChannel`.   I'm not married to this being `switch` based
   and may revise this to be driven by an `unordered_map` of
   opcode -> dispatcher method defined in `FuseChannel`.  Regardless,
   `Dispatcher.cpp` is now much slimmer and should be easier to
   replace by rolling it together into `EdenDispatcher.cpp` in
   the future should we desire to do so.
6. This diff disables dispatching `poll` and `ioctl` calls.  We
   didn't make use of them and their interfaces are a bit fiddly.
7. `INTERRUPT` is also disabled here.  I will re-enable it in
   a follow-up diff where I can also revise how we track outstanding
   requests for graceful shutdown.
8. I've imported `fuse_kernel.h` from libfuse.  This is included
   under the permissive 2-clause BSD license that it allows for
   exactly this integration purpose.

Reviewed By: simpkins

Differential Revision: D6576472

fbshipit-source-id: 7cb088af5e06fe27bf22a1bed295c18c17d8006c
2018-01-02 16:36:16 -08:00
Wez Furlong
afee9ce448 FileInode blob import is missing error handling
Summary:
Easy to overlook this; the issue is that we need to explicitly
do something about the error case when we're stitching together Promises
by hand, otherwise we will silently drop exceptions.

Flat manifest imports are failing in `RestartTestHg` in master
at the moment.  That error was silently being swallowed and the test would
hang until it timed out.

This is an uglyish hack to explicitly propagate the error condition so that
that test will error out.

This diff doesn't fix the source of the manifest import issue; that is addressed
in the next diff (turned out to be that the `--takeover` flag was not being
passed correctly)

Reviewed By: bolinfest

Differential Revision: D6627973

fbshipit-source-id: b7093890f543618a11682e939f8802f1309831d4
2017-12-22 12:36:25 -08:00
Philip Jameson
8604b8f5b0 Migrate TARGETS files from @/ to //
Summary:
This is a codemod to change from using @/ to // in basic cases.
- TARGETS files with lines starting with @/ (but excluding @/third-party:
- autodeps lines in source and TARGETS files ( (dep|manual)=@/ ), excluding @/third-party
- Targets in string macros

The only thing left of the old format should be @/third-party:foo:bar

drop-conflicts

Reviewed By: ttsugriy

Differential Revision: D6605465

fbshipit-source-id: ae50de2e1edb3f97c0b839d4021f38d77b7ab64c
2017-12-20 16:57:41 -08:00
Adam Simpkins
e9567ba6d4 improve short-circuiting logic on dry-run checkouts
Summary:
Update the logic for dry-run checkouts to exit early whenever we hit a
directory that is unmodified from the original source control state.  In this
case we can skip this entire subdirectory since we know there cannot be any
conflicts.

This should make dry-run checkout operations much faster in cases where there
are lots of changes between the source and destination source control trees,
but the working directory state has relatively few modified files.

Reviewed By: bolinfest

Differential Revision: D6605282

fbshipit-source-id: b5423749f3d47b10ed8d599ffaa0667c72fbaec2
2017-12-19 20:54:32 -08:00
Adam Simpkins
a8cbe6593a reduce calls to JournalDiffCallback::performDiff() during checkout
Summary:
Previously the checkout code always called `JournalDiffCallback::performDiff()`
to get the list of unclean files before starting the checkout operation.  After
the checkout completed it called `JournalDiffCallback::performDiff()` to get
the unclean files after the checkout operation.

Making both diff calls should be unnecessary: the checkout code can only modify
files that were unclean before the checkout (in the case of a `FORCEe` checkout)
or files that were modified between the source and destination source control
trees.  Therefore the `performDiff()` call after checkout completes should be
unnecessary, and can be removed.

This diff also eliminates the initial `performDiff()` call for `DRY_RUN`
checkouts.  We do not add a journal entry at all for `DRY_RUN` operations, so
we can skip this diff computation.

Reviewed By: wez

Differential Revision: D6455969

fbshipit-source-id: 20e0ac0d16d1fde844c1d6165a96611bfb370597
2017-12-19 15:12:20 -08:00
Chad Austin
f00d40b6e1 verify FileHandle is never copied nor moved (it doesn't support it yet)
Summary:
I almost added a copy in a later diff and realized it would
have let me, but done the wrong thing.

Reviewed By: wez

Differential Revision: D6585810

fbshipit-source-id: 15295d04b06df397113be6080e1f2f6b8a473745
2017-12-19 11:35:46 -08:00
Sergey Zhupanov
58b472b9d0 Added type identification capability to InodeBase.
Summary: Added type identification capability to InodeBase and its descendants FileInode and TreeInode.

Reviewed By: simpkins

Differential Revision: D6564902

fbshipit-source-id: ce9300102d6d6d1c42616eb1e32042f21f6e6cce
2017-12-14 16:41:39 -08:00
Chad Austin
2f22a9f534 introduce a type representing the unbounded eden cpu pool
Summary:
Add EdenCPUThreadPool and UnboundedQueueThreadPool types to make it clearer
that it's always okay for prefetch, deferred diff entry, and hg import to
shuttle work back to the main thread pool.

This diff changes no behavior - it just makes some invariants explicit.

Reviewed By: wez, simpkins

Differential Revision: D6504117

fbshipit-source-id: 3400ad55c00b3719ecba31807fd992442f622cd9
2017-12-12 12:35:35 -08:00
Sergey Zhupanov
b6394ac357 Added user and general system level gitignore
Summary:
Added to Eden capability to incorporate default user and general system level gitignore files.
NOTE: Work in progress, sending the review out to calibrate/ensure I am on right track.

Reviewed By: simpkins

Differential Revision: D6482863

fbshipit-source-id: 9834ca1a577a9599a1f8cb2243dca4e714866be8
2017-12-08 12:52:51 -08:00
Chad Austin
8a6d0592f7 allow returning the open file handle before the load/materialize completes
Summary:
There's no technical reason to block an open() request until the data
load / materialization returns.  This change returns immediately from
open() and then waits if necessary in a subsequent write() call.

Reviewed By: wez

Differential Revision: D6391486

fbshipit-source-id: 862f87e3c3a0d760bacb0f8ca7acc479037fec2f
2017-12-05 11:21:26 -08:00
Chad Austin
d112d63870 remove all direct calls to clock_gettime and system_clock::now
Summary:
Follow-up to comments in D6466209.  All access to the clock goes
through the Clock interface, making time deterministic in unit tests.

Reviewed By: simpkins

Differential Revision: D6477973

fbshipit-source-id: 24e51bdb52d0d079b34d91598d2e787d361f2525
2017-12-05 10:06:50 -08:00
Chad Austin
70f1bba3d6 test that asserts a new file inode's timestamps match the creation time, not the last checkout time
Summary: Follow-up from D6366189. First use of the new FakeClock!

Reviewed By: simpkins

Differential Revision: D6466209

fbshipit-source-id: 4d4d8a9a83df2bee11149e7a0cbddaaf734d0e04
2017-12-05 10:06:50 -08:00
Chad Austin
f91ae520b2 introduce a Clock seam for testability
Summary:
Introduce a Clock seam.  This will allow us to write tests around
ctime, mtime, and atime logic.

Reviewed By: wez

Differential Revision: D6392543

fbshipit-source-id: 1721d76d2364b135b4ef5c078ef60f7f8526259e
2017-12-05 10:06:48 -08:00
Chad Austin
dcba28b47f only call materializeInParent() when the inode state actually transitions to materialized
Summary:
open() called materializeInParent unconditionally, and setattr never
called it, implying it was possible to truncate a file without
materializing the parent.  This change makes sure to precisely call
materializeInParent whenever the state transitions to materialized.

Reviewed By: wez

Differential Revision: D6389794

fbshipit-source-id: 1e740e133a83d5090a6b9801154b7eaeccb07f22
2017-12-05 10:06:47 -08:00
Chad Austin
bb69c9b695 simplify materialization and reduce file reopenings
Summary:
To make the materialization code paths a bit clearer, this decouples
materialization from a blob and truncation.  It also caches opened
files if openCount > 0 in both the truncation and materialization from
blob paths.

Reviewed By: wez

Differential Revision: D6388318

fbshipit-source-id: c95a85f5bdaa405130f2f7260143592cdc90d45e
2017-12-04 15:13:43 -08:00
Adam Simpkins
1b86627d43 logging: update initialization code to use the new LogConfig logic
Summary:
Replace the initLoggingGlogStyle() function with a more generic initLogging()
function that accepts a log config string to be parsed with parseLogConfig().

Reviewed By: bolinfest, yfeldblum

Differential Revision: D6342086

fbshipit-source-id: fb1bffd11f190b70e03e2ccbf2b30be08d655242
2017-12-01 17:07:56 -08:00
Adam Simpkins
f3d9dcbc4d speed up hg update --clean operations
Summary:
Update TreeInode::computeCheckoutActions() to short circuit on non-materialized
directories that are identical to both the destination and source state.  This
speeds up `hg update --clean` operations by allowing us to skip portions of the
tree that do not require changes.

This does not have much effect for update operations without `--clean`: those
already short-circuited the operation in `TreeInode::processCheckoutEntry()`
when the source and destination hashes were the same.  That code cannot
short-circuit in the forced update case, since the forced update may have to
revert local modifications.

Reviewed By: bolinfest

Differential Revision: D6455970

fbshipit-source-id: 393acb3272745751a56e06dba0c7505ff2bfad44
2017-11-30 20:35:32 -08:00
Michael Bolin
5e2afa735f Change how the UNTRACKED_ADDED conflict and merges are handled.
Summary:
Previously, we used the Mercurial code `g` when faced with an `UNTRACKED_ADDED`
file conflict, but that was allowing merges to silently succeed that should not
have. This revision changes our logic to use the code `m` for merge, which
unearthed that we were not honoring the user's `update.check` setting properly.

Because we use `update.check=noconflict` internally at Facebook, we changed the
Eden integration tests to default to verifying Hg running with this setting. To
support it properly, we had to port this code from `update.py` in Mercurial to
our own `_determine_actions_for_conflicts()` function:

```
if updatecheck == 'noconflict':
    for f, (m, args, msg) in actionbyfile.iteritems():
        if m not in ('g', 'k', 'e', 'r', 'pr'):
            msg = _("conflicting changes")
            hint = _("commit or update --clean to discard changes")
            raise error.Abort(msg, hint=hint)
```

However, this introduced an interesting issue where the `checkOutRevision()`
Thrift call from Hg would update the `SNAPSHOT` file on the server, but
`.hg/dirstate` would not get updated with the new parents until the update
completed on the client. With the new call to `raise error.Abort` on the client,
we could get in a state where the `SNAPSHOT` file had the hash of the commit
assuming the update succeeded, but `.hg/dirstate` reflected the reality where it
failed.

To that end, we changed `checkOutRevision()` to take a new parameter,
`checkoutMode`, which can take on one of three values: `NORMAL`, `DRY_RUN`, and
`FORCE`. Now if the user tries to do an ordinary `hg update` with
`update.check=noconflict`, we first do a `DRY_RUN` and examine the potential
conflicts. Only if the conflicts should not block the update do we proceed with
a call to `checkOutRevision()` in `NORMAL` mode.

To make this work, we had to make a number of changes to `CheckoutAction`,
`CheckoutContext`, `EdenMount`, and `TreeInode` to keep track of the
`checkoutMode` and ensure that no changes are made to the working copy when a
`DRY_RUN` is in effect.

One minor issue (for which there is a `TODO`) is that a `DRY_RUN` will not
report any `DIRECTORY_NOT_EMPTY` conflicts that may exist. As `TreeInode` is
implemented today, it is a bit messy to report this type of conflict without
modifying the working copy along the way.

Finally, any `UNTRACKED_ADDED` conflict should cause an update to
abort to match the behavior in stock Mercurial if the user has the following
config setting:

```
[commands]
update.check = noconflict
```

Though the original name for this setting was:

```
[experimental]
updatecheck = noconflict
```

Although I am on Mercurial 4.4.1, the `update.check` setting does not seem to
take effect when I run the integration tests, but the `updatecheck` setting
does, so for now, I set both in `hg_extension_test_base.py` with a `TODO` to
remove `updatecheck` once I can get `update.check` to do its job.

Reviewed By: simpkins

Differential Revision: D6366007

fbshipit-source-id: bb3ecb1270e77d59d7d9e7baa36ada61971bbc49
2017-11-29 21:50:34 -08:00
Adam Simpkins
71981cc504 fix state handling in EdenMount::destroy()
Summary:
This fixes a crash in EdenMount::destroy() if EdenMount::create() failed to
load the root inode.  Previously the code called shutdownImpl() in this case
which tried to unload all inodes and crashed since the root inode was null.

This also fixes EdenMount::destroy() to properly handle the FUSE_ERROR and
FUSE_DONE cases.

Reviewed By: wez

Differential Revision: D6434355

fbshipit-source-id: 39c5f4472d6ebbcf881b4c9c8c8fd67686032ec1
2017-11-29 14:36:39 -08:00
Chad Austin
a58eb1a13c improve strace logging for reads, writes, and opens
Summary: More useful logging!

Reviewed By: bolinfest

Differential Revision: D6427736

fbshipit-source-id: 9725c15091566b23211665ee6db6145f08d86d2e
2017-11-28 20:06:04 -08:00
Wez Furlong
28e74f1ba6 add scmGetStatusBetweenRevisions thrift call
Summary:
The goal is to provide a fast path for watchman to flesh
out the total set of changed files when it needs relay that information
on to consumers.

We choose not to include the full list in the Journal when checking out
between revisions because it will not always be needed and may be an
expensive `O(repo)` operation to compute.  This means that watchman
needs to expand that information for itself, and that is currently
a fairly slow query to invoke through mercurial.

Since watchman is responding to journal events from eden we know that
we have tree data for the old and new hashes and thus we should be
able to efficiently compute that diff.

This implementation is slightly awful because it will instantiate an
unlinked TreeInode object for one side of the query, and will in
turn populate any children that differ as it walks down the tree.
A follow on diff will look at making a flavor of the diff code that
can diff raw Tree objects instead.

Reviewed By: bolinfest

Differential Revision: D6305844

fbshipit-source-id: 7506c9ba1f4febebcdc283c414261810a3951588
2017-11-28 19:36:32 -08:00
Michael Bolin
33b31c4062 Remove excludes from a build rule that no longer exist.
Summary:
This should have been removed as part of D6179950.

Ideally, Buck would error when this happens, but apparently `glob()` does not
complain when patterns do not match any files, even when the pattern does not
contain any wildcards. There appears to be some code at Facebook that is
exploiting this behavior.

Reviewed By: simpkins

Differential Revision: D6421529

fbshipit-source-id: c6f982624e0e12a911bc12ab1e8239ba4358ea56
2017-11-28 01:35:56 -08:00
Chad Austin
200fefb024 set in-memory ctime properly when creating new FileInodes
Summary:
This corrects a bug where the in-memory timestamp for new files would
be set to the last checkout time instead of when the file was created.

Reviewed By: simpkins

Differential Revision: D6366189

fbshipit-source-id: c5fa8c779726d3a75c2d57b2a161293297eb9271
2017-11-21 09:21:29 -08:00
Chad Austin
7389babe42 update comments regarding O_EXCL behavior
Summary:
Per a discussion with wez, let's make it explicit in the comments that the kernel handles
O_EXCL for us.

Reviewed By: simpkins

Differential Revision: D6365157

fbshipit-source-id: 638f67cd89a9450ff084e0ef77c731ef738bf518
2017-11-21 09:21:29 -08:00
Chad Austin
0c8f577cd8 close FileInode file handle when there are no open file handles
Summary:
In some workloads we're seeing folks run out of file descriptors.
We forgot that we'd taken out the code that closes the underlying fds.
This diff takes a run at adding a simple counter of the open file handle
objects that is incremented when they are constructed and decremented
when they are destroyed.

When the count falls to zero we release the file handle.

Note that we unconditionally open files when we first load the inodes
from the overlay.  I tried to defer that open attempt and it broke
the timestamp overlay test.  I think we can revisit that aspect in
a follow on diff; for now we should be more resilient to transiently
opened files from things like ripgrep or similar.

Reviewed By: simpkins

Differential Revision: D6097090

fbshipit-source-id: 9a48220002e760fb1ffb8d7e2a68fa7036558b78
2017-11-21 09:21:29 -08:00
Michael Bolin
9ab42310c5 Directory was showing up as UNTRACKED_ADDED instead of its contents.
Summary:
This bug is part of a bigger issue in our Mercurial integration where
`UNTRACKED_ADDED` conflicts are being silently swallowed in our Hg extension
whereas stock Mercurial presents these as conflicts and forces the user to deal
with them. The Mercurial issues will be addressed in a follow-up change.

Reviewed By: simpkins

Differential Revision: D6365580

fbshipit-source-id: 831e27ce1da90ea605033b2b9988fe400ba404aa
2017-11-20 15:56:37 -08:00
Chad Austin
daa0f8ad5a Give FileInode's state an explicit tag
Summary:
In preparation for bringing D6097090 across the finish line, we need a
more explicit mechanism for determining which state the inode is in.
The issue is that whether an inode is materialized was checked in a
couple ways: the nonexistence of the hash field or the definedness of
the file field.  This diff introduces an explicit enum indicating the
state.

Reviewed By: simpkins

Differential Revision: D6325955

fbshipit-source-id: 3682a4ebc9330193baadbb33a4dd9845f26e59a6
2017-11-20 12:15:53 -08:00
Adam Simpkins
fbeb35cbdc fix issues tracking the last checkout time
Summary:
Eden attempts to initialize timestamps of newly loaded inodes with the time of
the last checkout operation performed in this mount.  Unfortunately it had a
number of bugs in this logic:

EdenMount had two separate fields attempting to track the last checkout time:
`lastCheckoutTime_` and `parentInfo_.lastCheckoutTime`.

Unfortunately neither field was actually updated on checkout operations.
Additionally, `lastCheckoutTime_` did not have any locking to allow it to be
updated.  `parentInfo_.lastCheckoutTime` did have locking, but it used the
mount point's checkout lock, so it could not be accessed during checkout
operations.

This diff removes `parentInfo_.lastCheckoutTime`, keeping only
`lastCheckoutTime_`.  It also converts `lastCheckoutTime_` to a
`struct timespec` since this is most often needed as a `timespec`.  It also
adds a new mountpoint-wide lock for synchronizing accessing to this variable.

Reviewed By: bolinfest

Differential Revision: D6356698

fbshipit-source-id: db54f9bb297b5febe4642e2b3fcc8055a6afc199
2017-11-19 15:47:13 -08:00
Chad Austin
38360c8563 make materializeForWrite private
Summary: More work towards encapsulating a FileInode's internal state machine.

Reviewed By: wez

Differential Revision: D6316013

fbshipit-source-id: 9c8303b35a0de1ba69207c7f59be88c5fb037ad8
2017-11-16 09:58:15 -08:00
Chad Austin
9217c5b56b refactor inode creation a bit, remove finishCreate()
Summary:
This is preparation for a change I'm preparing that makes the state
transitions in FileInode clearer and safer.

Reviewed By: wez

Differential Revision: D6304272

fbshipit-source-id: 493ee80517443432f790abf9806000eecb03651c
2017-11-16 00:29:24 -08:00
Adam Simpkins
c8c1ba5eab remove eden/fs/utils/test/TestChecks.h
Summary:
The gtest macros in this file were moved to folly/test/TestUtils.h
Update everything to just use folly/test/TestUtils.h directly.

Reviewed By: chadaustin

Differential Revision: D6301759

fbshipit-source-id: 7f2841c12d5bea15376f782fb3bf3bfef16039c7
2017-11-15 12:53:55 -08:00
Michael Bolin
e8d25ee211 Move the post-clone step from C++ to Python.
Summary:
Moving the post-clone step out of C++ makes it so that
`ClientConfig` in C++ no longer knows about `hooks` and requires
`RepoConfig` to know about `hooks`. This helps us reduce
`ClientConfig`'s dependency on `ConfigData`, as my next step
is to move the remaining information that `ClientConfig` gets from
`ConfigData` directly into the client's `edenrc` file under
`~/local/.eden`.

Reviewed By: chadaustin

Differential Revision: D6310544

fbshipit-source-id: dec7a21281ab49e0416b8872757970a4eff2d943
2017-11-14 14:06:25 -08:00
Michael Bolin
2d1eade7a7 Run the autodeps script on our build files.
Summary:
I created this change by running:

```
find eden -name TARGETS | grep -v eden/fs/fuse/TARGETS | grep -v eden/fs/service/TARGETS | xargs autodeps
```

apparently `eden/fs/fuse/TARGETS` and `eden/fs/service/TARGETS` have some
constructions that `autodeps` does not understand, so I filtered those out.

Reviewed By: StanislavGlebik

Differential Revision: D6319982

fbshipit-source-id: 7b3683d1507409dde6d6570e9b13811168aa6859
2017-11-14 11:18:19 -08:00
Chad Austin
587d0ad1ee Move Journal locking inside of Journal itself
Summary:
This is follow-up to the lock ordering issues in
StreamingSubscriber.  The Journal locks are now finer-grained and no
locks are held while the subscribers are invoked.  This change
prevents future deadlocks.

Reviewed By: wez

Differential Revision: D6281410

fbshipit-source-id: 797c164395831752f61cc15928b6d4ce4dab1b68
2017-11-10 19:57:49 -08:00
Chad Austin
75bd0c08ea remove future.get() call from FileInode::ensureDataLoaded
Summary:
With the subsequent diff that enables multiple concurrent
hg importers, I was seeing this deadlock during rebase; each of
the worker threads was being blocked until it saturated the various
thread pools and locked up the server.

This removes the blocking call and replaces it with a SharedPromise
to allow multiple callers to wait for the load.

Note that this changes the semantics of ensureDataLoaded slightly:
previously the blob load was synchronous while the write lock was
held.  Now we release the write lock until the load completes.

I've added some post-condition checks to validate that we don't
break any state.  I believe that our usage is such that we don't
do anything that might mess things up.  Am I missing anything?

Reviewed By: simpkins

Differential Revision: D6264900

fbshipit-source-id: 4aa2870d95f0f0ec48d87299978cb87af99e3969
2017-11-10 13:24:33 -08:00
Chad Austin
9981d7526c Avoid blocking to fetch the metadata when prefetching sha-1 is purely an optimization.
Summary:
Address some feedback on D6264900 by only storing the sha-1 in the
overlay when it's immediately available.  This avoids the possibility
of the FUSE thread getting blocked.

Reviewed By: simpkins

Differential Revision: D6292175

fbshipit-source-id: 06c2372724e58c485d9a302dde36c34885109acf
2017-11-10 09:07:59 -08:00
Michael Bolin
c6f59d25b8 Fix a crash that could occur when doing hg update .^ --merge.
Summary:
The underlying issue is that we were reporting a `MODIFIED_REMOVED`
conflict as a `MODIFIED_MODIFIED` conflict. This put us in a state where
Mercurial expected to find a file in the new manifest, but failed because the
file was not present in that revision, so no such file could be found.

Somewhat surprisingly, the appropriate handler for a `MODIFIED_REMOVED`
conflict already existed in our Mercurial extension, but there was no logic on
the server that would generate a `MODIFIED_REMOVED` conflict previous to
this change.

Like D6204916, this was an issue I ran into when trying to create a repro case
for the issue that was fixed in D6199215.

Reviewed By: wez

Differential Revision: D6270272

fbshipit-source-id: 6604eea00b0794cd44b01d2ba6b9ea10db32d556
2017-11-09 16:29:55 -08:00
Chad Austin
32ba74fe46 rename FileInode::getSHA1 to FileInode::getSha1
Summary: Make this function match our C++ guidelines.

Reviewed By: wez

Differential Revision: D6288591

fbshipit-source-id: 1a4f52a8c1e0497df938533fe29da10264eb1ccf
2017-11-09 15:52:42 -08:00
Adam Simpkins
107c2e1753 add debug logging for TreeInode::diff()
Summary:
Add log messages that will help debug the behavior of `TreeInode::diff()`

I added this since I saw a case where `getScmStatus()` was returning a file as
modified when it did not appear to have mode or contents changes.
Unfortunately we did not have any existing debug log messages for this, and the
problem went away after restarting edenfs, so I wasn't able to track it down.
Having these log messages will help debug this in the future if we run into it
again.

Reviewed By: bolinfest

Differential Revision: D6281905

fbshipit-source-id: 736028d6efe46a387bed6bf98d971685f83da3ec
2017-11-08 21:39:07 -08:00
Chad Austin
8b605a38c4 Document and enforce the invariants in FileInode's State variant
Summary: The comments and the code did not agree on what fields were valid when, so I corrected them and added runtime enforcement.

Reviewed By: wez

Differential Revision: D6260555

fbshipit-source-id: 13e35e22c44b9a5b4cb30cdfd48e2bf7b0e116d3
2017-11-07 16:27:59 -08:00
Michael Bolin
5d738193e5 Store Hg dirstate data in Hg instead of Eden.
Summary:
This is a major change to how we manage the dirstate in Eden's Hg extension.

Previously, the dirstate information was stored under `$EDEN_CONFIG_DIR`,
which is Eden's private storage. Any time the Mercurial extension wanted to
read or write the dirstate, it had to make a Thrift request to Eden to do so on
its behalf. The upside is that Eden could answer dirstate-related questions
independently of the Python code.

This was sufficiently different than how Mercurial's default dirstate worked
that our subclass, `eden_dirstate`, had to override quite a bit of behavior.
Failing to manage the `.hg/dirstate` file in a way similar to the way Mercurial
does has exposed some "unofficial contracts" that Mercurial has. For example,
tools like Nuclide rely on changes to the `.hg/dirstate` file as a heuristic to
determine when to invalidate its internal caches for Mercurial data.

Today, Mercurial has a well-factored `dirstatemap` abstraction that is primarily
responsible for the transactions with the dirstate's data. With this split, we can
focus on putting most of our customizations in our `eden_dirstate_map` subclass
while our `eden_dirstate` class has to override fewer methods. Because the
data is managed through the `.hg/dirstate` file, transaction logic in Mercurial that
relies on renaming/copying that file will work out-of-the-box. This change
also reduces the number of Thrift calls the Mercurial extension has to make
for operations like `hg status` or `hg add`.

In this revision, we introduce our own binary format for the `.hg/dirstate` file.
The logic to read and write this file is in `eden/py/dirstate.py`. After the first
40 bytes, which are used for the parent hashes, the next four bytes are
reserved for a version number for the file format so we can manage file format
changes going forward.

Admittedly one downside of this change is that it is a breaking change.
Ideally, users should commit all of their local changes in their existing mounts,
shutdown Eden, delete the old mounts, restart Eden, and re-clone.

In the end, this change deletes a number of Mercurial-specific code and Thrift
APIs from Eden. This is a better separation of concerns that makes Eden more
SCM-agnostic. For example, this change removes `Dirstate.cpp` and
`DirstatePersistance.cpp`, replacing them with the much simpler and more
general `Differ.cpp`. The Mercurial-specific logic from `Dirstate.cpp` that turned
a diff into an `hg status` now lives in the Mercurial extension in
`EdenThriftClient.getStatus()`, which is much more appropriate.

Note that this reverts the changes that were recently introduced in D6116105:
we now need to intercept `localrepo.localrepository.dirstate` once again.

Reviewed By: simpkins

Differential Revision: D6179950

fbshipit-source-id: 5b78904909b669c9cc606e2fe1fd118ef6eaab95
2017-11-06 19:56:49 -08:00
Chad Austin
0003adc4fb make FileInode::stat() asynchronous
Summary: Continue moving the asynchrony of loading closer to the state access so, in a future world, we still behave if unloading occurs during access.

Reviewed By: simpkins

Differential Revision: D6238523

fbshipit-source-id: 722fe5bba90b55204d50393314d225f42680409b
2017-11-03 19:08:25 -07:00
Chad Austin
536bd6e298 Change FileInode::readAll's public API to be async
Summary: To fix up the invariants in FileInode's API, we intend to remove ensureDataLoaded() and materializeForWrite().  But first I'm going to see if there is any pain caused by removing their calls.

Reviewed By: simpkins

Differential Revision: D6234049

fbshipit-source-id: c39c6d018d164b32903414d3750b875a897af210
2017-11-03 17:51:42 -07:00
Chad Austin
8b9261f2a1 run clang-format across all C++ files
Summary:
Per discussion with bolinfest, this brings Eden in line with clang-format.

This diff was generated with `find . \( -iname '*.cpp' -o -iname '*.h' \) -exec bash -c "yes | arc lint {}" \;`

Reviewed By: bolinfest

Differential Revision: D6232695

fbshipit-source-id: d54942bf1c69b5b0dcd4df629f1f2d5538c9e28c
2017-11-03 16:02:03 -07:00
Chad Austin
f79672e8ec clean up partially-written symlinks if symlink creation fails
Summary: If writing out the symlink file in the overlay fails, clean up the file before releasing the lock.

Reviewed By: wez

Differential Revision: D6234214

fbshipit-source-id: 91ccf917a26cc1a73c3963dea7dd87364857fa03
2017-11-03 15:25:34 -07:00
Adam Simpkins
07b61591ca avoid holding TreeInode locks while locking the Journal
Summary:
Most functions in TreeInode that call Journal::addDelta() release the
TreeInode::contents_ lock before locking the journal.  However, `doRename()`
locked the journal while still holding the contents_ locks for the directories
affected by the rename.

This updates `doRename()` to make sure we release the TreeInode locks properly
before attempting to update the journal.  This should help ensure that we don't
have any lock ordering issues here.

Reviewed By: bolinfest

Differential Revision: D6212075

fbshipit-source-id: 84503acf47e9d97b81075932326825832cef9514
2017-11-01 20:43:43 -07:00
Ryan Menezes
22b2ccf616 thrift_library rename java{,deprecated}
Summary:
For a while, the recommended approach (e.g. from folks on the thrift team, from folks on the javafoundations team) has been to use `languages = ["java-swift"]`. This renaming brings the code in line with the recommendation. There are no actual changes to any builds, this is just a rename.

This is the second diff in a small stack. It's a fully automated change that uses buildozer to rename `*-java` rules to `*-javadeprecated`.

Differential Revision: D6189950

fbshipit-source-id: a08ba86cb92293a07eceb4b6b29385c7bf647b72
2017-11-01 14:34:07 -07:00
Yedidya Feldblum
b2f5376cea Move folly/Array.h
Summary: [Folly] Move `folly/Array.h` to `folly/container/`.

Reviewed By: luciang

Differential Revision: D6182858

fbshipit-source-id: 59340b96058cc6d0c7a0289e316bbde98c15d724
2017-10-29 03:42:55 -07:00
Michael Bolin
0f4ba60602 Update the hg/post-clone hook to write the .hg/dirstate file.
Summary:
Now that we make use of the `.hg/dirstate` file, we should ensure that it is
initialized correctly. This takes the commit hash from the `SNAPSHOT` file and
passes it as an argument to the `post-clone` hook. In the Hg `post-clone` hook,
it writes the `.hg/dirstate` file such that the first 20 bytes are the binary
version of the commit hash and the next 20 bytes are nul bytes.

Reviewed By: simpkins

Differential Revision: D6174440

fbshipit-source-id: 29d17f88ca3f63fa6490e1db88bc2121aced74d6
2017-10-27 13:35:26 -07:00
Wez Furlong
d3202383c1 tidy up journal subscribers on unmount
Summary:
We have a couple of issues with the watchman/eden integration:

1. If you "win" the race, you can cause a segfault during shutdown
by changing files during unmount.  This causes the journal updating
code to trigger a send to the client, but the associated eventBase
has already been destroyed.

2. We don't proactively send any signal to the subscriber (in practice: watchman)
when we unmount.  Watchman detects the eden shutdown by noticing that its
socket has closed but has no way to detect an unmount.

This diff tries to connect the unmount with the set of subscribers and tries
to cause the thrift socket to close out.

Reviewed By: bolinfest

Differential Revision: D6162717

fbshipit-source-id: 42d4a005089cd9cddf204997b1643570488f04c3
2017-10-27 09:01:57 -07:00
Michael Bolin
ac5b213e92 Include the dirstate tuples and copymap when backing up the dirstate.
Summary:
Previously, the `savebackup()` and `restorebackup()` methods in `eden_dirstate`
only retained the parent commit hashes. With this change, now the dirstate tuples
and entries in the copymap for the dirstate are also included as part of the saved
state.

Failing to restore all of the state caused issues when doing things like aborting
an `hg split`, as observed by one of our users. Although this fix works, we ultimately
plan to move the responsibility for persisting dirstate data out of Eden and into the
Hg extension. Then the data will live in `.hg/dirstate` like it would for the default
dirstate implementation.

Reviewed By: simpkins

Differential Revision: D6145420

fbshipit-source-id: baa077dee73847a47cc171cd980cdd272b3a3a99
2017-10-25 22:36:06 -07:00
Adam Simpkins
2e6ed25612 flush kernel caches properly for empty directories removed by checkout
Summary:
When performing an source control checkout operation, we attempt to remove
directories that are empty after the checkout.  However, this code path was
missing a call to flush the kernel cache for these directories.

As a result, even though eden thought the directory not longer existed, and
would not report it in `readdir()` results, the kernel would return stale
information from its cache when explicitly accessing this path.

Reviewed By: bolinfest

Differential Revision: D6151543

fbshipit-source-id: 6031feb268ff6f980c885efb26c3d43243dec3f4
2017-10-25 16:51:56 -07:00
Adam Simpkins
35c50ea4e3 add more debug logging of checkout operations
Summary:
Add a few extra debug logs to record `processCheckoutEntry()` and
`saveOverlayPostCheckout()` calls.

Reviewed By: bolinfest

Differential Revision: D6151544

fbshipit-source-id: ca6faa8fd1fe53df1e70305f5527360c918841d1
2017-10-25 16:51:56 -07:00