Commit Graph

33 Commits

Author SHA1 Message Date
Jyothsna Konisa
7e230ba743 Implementing setattr in InodeBase (FileInode::setattr removal)
Summary: Removed `FileInode::setattr` from `FileInode`  and added a helper function `setInodeAttr` to perform FileInode or TreeInode specific setattr operations in `InodeBase::setattr`. This diff contains implementation of setattr for FileInode i.e for files, will add setattr implementation for directories in another diff.

Reviewed By: simpkins

Differential Revision: D5544968

fbshipit-source-id: 089491d07a603e111966987ef390b6e597aba28c
2017-08-14 13:36:37 -07:00
Jyothsna Konisa
3f046593a8 Wrapper for TimeStamps & helper function to set timestamps in setattr.
Summary:
1. Added a new structure `InodeBase::InodeTimestamps` to wrap atime,ctime,mtime together. This new structure helps in avoiding usage of `struct stat` for timestamps.
2. Modified function `Overlay::openFile` ,`Overlay::updateTimestampToHeader`, `Overlay::deserializeOverlayDir`, `Overlay::parseHeader` to use this new structure for timestamps instead of `struct stat`. Also, modified code in places where this change is being affected.
3. Added new helper methods `FileInode::setattrTimes`  and `TreeInode::setattrTimes` to set timestamps in FileInode and TreeInode during setattr. Implementation of setattr for FileInode and TreeInode is in the diffs stacked above this diff.
4. Replaced atime, ctime, mtime in `FileInode::State`, `TreeInode::Dir` to `FileInode::State::timeStamps` and `TreeInode::State::timeStamps`. Made other necessary changes to support this change.

Reviewed By: simpkins

Differential Revision: D5596854

fbshipit-source-id: 2786b7b695508a62fdf8f7829f1ce76054b61c52
2017-08-11 11:36:07 -07:00
Jyothsna Konisa
20c62ae2bf Refactoring FileInode::setattr
Summary: Currently we have two functions `FileInode::setattr` and `FileInode::setAttr` which are used to set given attributes to a `FileInode`. Merged both the functions in to one function called `FileInode::setattr` and removed `FileInode::setAttr`.

Reviewed By: wez

Differential Revision: D5538490

fbshipit-source-id: ec241fad25d6e4694865e5fc3c0a3500e4838bdd
2017-08-04 20:19:20 -07:00
Jyothsna Konisa
6aa6e547d6 Reading and writing timestamps in to overlay files
Summary:
Added a new function `InodeBase::updateOverlayHeader` and implemented `FileInode::updateOverlayHeader` and `TreeInode::updateOverlayHeader` to update inmemory timestamps to overlay header when an inode is unreferenced.

Added helper functions in `Overlay` class to read and update timestamps in to the overlay file. Also,modified `Overlay::loadOverlayDir` to read and populate timestamps from overlay header in to treeinode.

Modified constructor of `FileInode::state` to read timestamps from overlay file and to populate inode timestamps.

Added test case to check if time stamps are updated and read correctly on remount.

Fixed a lint warning in TARGETS file

Reviewed By: simpkins

Differential Revision: D5535429

fbshipit-source-id: f6b758f70101c65d316a35101aacc9a3363f7aed
2017-08-04 20:19:20 -07:00
Michael Bolin
50191d5bbd Fix a race condition in FileInode::readAll().
Summary:
In testing, we discovered a case where concurrent Hg operations in EdenFS would
//sometimes// fail with `ECONNREFUSED` when trying to read
`<eden-mount>/.eden/socket`.

This was very confusing, as the standard reasons for `ECONNREFUSED` did not seem
to apply:
- We verified that Eden had not crashed.
- We verified that Eden's UNIX domain socket had a sufficiently large backlog
  (1024) such that we should not be at risk of exhausting it with two simultaneous
  Hg commands.

It turned out that there was a race condition in our `readlink()` command, which
could cause `<eden-mount>/.eden/socket` to resolve to the wrong path. Failing to
connect to this path manifested itself as an `ECONNREFUSED` error.

It turned out that `readlink()` used `FileInode::readAll()`, which was
performing an `lseek()` followed by a `read()` on a file descriptor while the
descriptor was protected by a //read lock// instead of a //write lock//. Because
the `lseek()` causes a state change, it needs to be protected by a write lock.
Changing the type of the lock fixed the issue.

The only other caller of `FileInode::readAll()` appears to be in
`TreeInode::loadGitIgnoreThenDiff()`, so presumably this fixes a possible race
condition there, as well.

Reviewed By: simpkins

Differential Revision: D5533001

fbshipit-source-id: 86cf84c45463b2ae194d6f46909ea67c0f71d065
2017-07-31 19:08:09 -07:00
Jyothsna Konisa
e4fefa3e69 Adding Timestamps to TreeInode class and intializing timestamps to lastcheckout time
Summary: Added atime,ctime,mtime for tracking timestamps for directories inmemory and initialized them to the last checkout time during the creation of TreeInode.

Reviewed By: bolinfest

Differential Revision: D5440950

fbshipit-source-id: 639cf1ce6722f80dde35d33849aa712aa30301a8
2017-07-27 18:25:01 -07:00
Jyothsna Konisa
19df19d994 Adding lastCheckoutTime to EdenMount and initializing timestamps of FileInode with lastCheckoutTime
Summary:
Added a new data member lastCheckoutTime to EdenMount class to store the time when checkout operation is performed. Also added a method to get the last checkout time which internally returns the lastCheckoutTime in EdenMount class.

Added new fields atime,mtime,ctime in FileInode::State structure to keep track of timestamps in memory. Initialzed timestamps in FileInode::State constructor by calling getLastCheckOutTime from EdenMount class.

Still have to add timestamp tracking for directories and have to initialize them with lastCheckout time.This probably will be done in a seperate diff.

Reviewed By: bolinfest

Differential Revision: D5437682

fbshipit-source-id: e3d6b1bc0c2192538dd3b0d9a6017ceb3ca0843d
2017-07-27 11:52:31 -07:00
Jyothsna Konisa
20cd12b31a Moving FileData methods to FileInode
Summary:
Moved all the member functions from `FileData` class to `FileInode` class
and made `FileInode` methods independent of shared `FileData` object.
Removed `FileData.h` and `FileData.cpp` files as they are not needed anymore.

Modified functions `FileInode::getSHA1()` and `FileInode::isSameAsFast` and
modified few testcases which are currently using `FileData` class and made
sure that all the test cases are passing.

Reviewed By: bolinfest

Differential Revision: D5430128

fbshipit-source-id: 3e8e6c490e92e4e602355e4ce39b67c450ec53f8
2017-07-26 23:39:35 -07:00
Jyothsna Konisa
371d7f889f Refactoring FileInode FileData.
Summary:
1.Refactored FileInode and FileData code.
2.Moved some data members of file data into struct State inside file inode
3.Refactoring code such that FileData and FileInode classes are eventually moved to FileInode class.

Reviewed By: simpkins

Differential Revision: D5414427

fbshipit-source-id: cf24721a65541ddfdec7ead4a035de4da3fd5bb5
2017-07-17 13:20:45 -07:00
Yedidya Feldblum
d680237331 Remove construct_in_place
Summary:
[Folly] Remove `construct_in_place`.

It is an alias for `in_place`, and unnecessary.

Reviewed By: Orvid

Differential Revision: D5362354

fbshipit-source-id: 39ce07bad87185e506fe7d780789b78060008182
2017-07-02 10:35:18 -07:00
Adam Simpkins
a521832407 simplify the Dirstate::removeAll() code
Summary:
This replaces the shouldFileBeDeletedByHgRemove() function with a much simpler
and safer check.

It turns out this code was more complicated than it needed to be: it looked up
the inode in question and confirmed that it still existed, even though it's
calling function had already previously looked up the inode object.

I believe this deletes the last place in the code that still assumes that an
InodeBase object must be loaded if the inode has previously been materialized.
This also removes one of the last remaining places that directly holds the
TreeInode contents_ lock outside of TreeInode.cpp.

Reviewed By: bolinfest

Differential Revision: D4968834

fbshipit-source-id: a37bc0d7889eb81cca5b045cbc82732a53ef53d4
2017-05-01 18:54:41 -07:00
Adam Simpkins
a6ae3edab9 move eden/utils and eden/fuse into eden/fs
Summary:
This change makes it so that all of the C++ code related to the edenfs daemon
is now contained in the eden/fs subdirectory.

Reviewed By: bolinfest, wez

Differential Revision: D4889053

fbshipit-source-id: d0bd4774cc0bdb5d1d6b6f47d716ecae52391f37
2017-04-14 11:39:02 -07:00
Adam Simpkins
d6f7a2f91a report timestamps on non-materialized files
Summary:
This diff fixes FileData::stat() so that we report reasonable timestamp values
on non-materialized files, rather than always leaving them as 0.  We set the
timestamps to the time that we created the FileInode.  This ensures that
timestamps are updated correctly when files are modified by a checkout
operation.

Note that for materialized files the code reports the timestamp of the overlay
file.  This diff does not modify that behavior.  However, this behavior is
incorrect, as the overlay file timestamps are not updated by a FUSE client
opening, modifying, then closing a file (since we keep the underyling overlay
file handle open, and don't close it).

In the future we'll need to implement our own tracking of atime, mtime, and
ctime values.  We should probably store these in a header inside the overlay
file.  For now, this diff is a stop-gap measure that ensures we at least update
non-materialized file timestamps correctly on checkouts.

Reviewed By: bolinfest

Differential Revision: D4765632

fbshipit-source-id: 478da6441e213cdfe830f1c5129212182ce4eeb0
2017-04-03 15:50:32 -07:00
Wez Furlong
7c6f9608c2 add basic mknod support
Summary:
this is the bare minimum to support creating unix domain sockets.

We only support using mknod to create a unix socket; other uses will yield an error.

I've added an rdev field as a sibling of the existing mode field that we track,
as that is the additional parameter that we need to track as part of the
special file node.

Special file nodes are tracked in the overlay as empty files.

Reviewed By: bolinfest

Differential Revision: D4774099

fbshipit-source-id: 0824b7e509063faa8bede7aff82a7c51930c4f83
2017-03-30 23:53:05 -07:00
Adam Simpkins
d101f404dc add an EdenMount::diff() method
Summary:
This begins adding an EdenMount::diff() method, which walks through the inode
tree and reports differences from the current source control tree state.

My intent is to eventually update the Dirstate code to use this diff()
function, and to remove the existing getModifiedDirectories() logic.  The
getModifiedDirectories() code is currently incorrect, as it reports
materialized directories, which is not the same as directories that are
modified from the current source control state.

The ignore processing logic is not currently implemented in EdenMount::diff(),
but it should be relatively straightforward to add in a subsequent diff.

Reviewed By: bolinfest

Differential Revision: D4726048

fbshipit-source-id: ad0bb3b5d72bb3830f60fc2b2e56a81217c35353
2017-03-21 12:06:44 -07:00
Adam Simpkins
d1e1e4c621 refactor FileInode to avoid using its parent's TreeInode::Entry
Summary:
Refactor FileInode and FileData so that they no longer store the
TreeInode::Entry that refers to this file.  The TreeInode::Entry is owned by
the parent TreeInode and is not safe to access without holding the TreeInode
contents_ lock, which the FileInode code never did.  Additionally, once a
FileInode is unlocked the TreeInode::Entry is destroyed.  Previously the
FileInode code would retain its pointer to this now invalid data, and could
still dereference it.

In the future I think it might be worth refactoring the FileInode/FileData
split a bit more, but this at least addresses the issues around invalid
accesses to entry_.

Reviewed By: bolinfest

Differential Revision: D4688058

fbshipit-source-id: 17d5d0c4e756afc6e3c4bb279cb1bb5231f3134f
2017-03-10 18:29:29 -08:00
Adam Simpkins
2369f6f810 address some issues with materializing inodes
Summary:
This changes a couple aspects of the materialization process:

- Write out child files in the overlay before their parent.  If we throw an
  exception or crash partway through this process, it is better to have the
  child not marked materialized in its parent, rather than to have the parent
  indicate that the child is materialized but to not actually have any overlay
  data for the child.  In the former case we will still load the correct child
  data the next time we need to, but in the latter case we would fail to load
  the child correctly.

- Hold the rename lock while materializing our parent directories, to ensure
  that we materialize the correct parent, and it cannot change while we are
  trying to perform the materialization.

- Make the parent responsible for modifying the child's TreeInode::Entry.  This
  data is owned by the parent and is protected by the parent's contents_ lock.
  The child really shouldn't ever be directly accessing this data without
  holding the parent's contents_ lock.

Reviewed By: bolinfest

Differential Revision: D4688057

fbshipit-source-id: 2662f79cb7d7febb086f4e0888a3d96a580c4bfa
2017-03-10 18:29:29 -08:00
Adam Simpkins
dcf8e6a3a2 add an EdenMount::resetCommit() method
Summary:
Add a method to reset the current commit without changing the working
directory state, similar to "hg reset" and "git reset --soft".

This also adds a new EXPECT_FILE_INODE() check for use in the unit tests,
and FileInode::getPermissions() and FileData::readFull() methods to support
this check.

Reviewed By: wez

Differential Revision: D4641476

fbshipit-source-id: 1e516774fe8e292a8d82cc2c354619374a3abe37
2017-03-02 14:24:10 -08:00
Wez Furlong
c543f89404 add symlink support to the overlay
Summary:
Previously, we would only allow you to consume a symlink that was
checked into a revision, but not allow you to create a new one.

This diff adds support for making new symlinks.

It turns out that the code that we had for readlink had an unused code path for
reading an actual symlink out of the overlay.  My first pass at this diff tried
to make the materialization code generate such a symlink, but it was breakin
some other assumptions in the rest of the code.

This version of the code just stores the symlink target in the file contents.
This means that we can simplify readlink to just calling `readAll` on the
underlying file data, and that will load the contents out of the storage layer
if the file wasn't materialized.  This helps simplify things a bit more.

Reviewed By: bolinfest, simpkins

Differential Revision: D4604016

fbshipit-source-id: 3138d0f9880639d2bbeaf4bb03bef3f021c3ecb3
2017-03-02 08:18:45 -08:00
Adam Simpkins
0687431924 implement EdenMount::checkout()
Summary:
This is the initial code for implementing checkout.

This isn't quite 100% implemented yet, but I think it's worth checking in this
code as-is, and getting the remaining functionality done in separate diffs.
In particular, a few operations aren't implemented:
- Removing a directory that was deleted in the new revision
- Replacing a directory that was replaced with a file or symlink in the new
  revision
- When doing a forced update, replacing a file or directory that did not exist
  in the old revision, but that was created locally in the working directory,
  and also exists in the new revision.

Reviewed By: wez

Differential Revision: D4538516

fbshipit-source-id: 5bb4889b02f23ab2048fcae2c8b7614340181aa6
2017-02-15 20:33:31 -08:00
Adam Simpkins
fed342da30 store overlay files using inode numbers instead of paths
Summary:
Refactor the Overlay code to store data using inode numbers rather than the
affected file's path in the repository.  This simplifies the TreeInode code a
bit, as we no longer have to rename overlay files to stay in sync with the file
paths.  This also eliminates some crashes when trying to update overlay files
for inodes that have been unlinked (and hence no longer have a path).  This
also includes a few fixes to avoid writing journal entries for unlinked files
too.  Additionally this contains a few fixes to how mode bits are stored in the
overlay, and fixes a bug where create() was ignoring the mode argument.

Reviewed By: wez

Differential Revision: D4517578

fbshipit-source-id: c1e31497dcf62c322b0deff72b0a02675b0509ab
2017-02-10 14:17:52 -08:00
Adam Simpkins
251da81f36 update all copyright statements to "2016-present"
Summary:
Update copyright statements to "2016-present".  This makes our updated lint
rules happy and complies with the recommended license header statement.

Reviewed By: wez, bolinfest

Differential Revision: D4433594

fbshipit-source-id: e9ecb1c1fc66e4ec49c1f046c6a98d425b13bc27
2017-01-20 22:03:02 -08:00
Adam Simpkins
3a73253057 add new InodePtr classes
Summary:
This defines our own custom smart pointer type for Inode objects.  This will
provide us with more control over Inode lifetime, allowing us to decide if we
want to unload them immediately when they become unreferenced, or keep them
around for a while.

This will also allow us to fix some memory management issues around EdenMount
destruction.  Currently we destroy the EdenMount immediately when it is
unmounted.  This can cause issues if other parts of the code are still holding
references to Inode objects from this EdenMount.  Our custom InodePtr class
will also allow us to delay destroying the EdenMount until all of its Inodes
have been destroyed.

This diff adds the new pointer types and updates the code to use them, but does
not actually implement destroying unreferenced inodes yet.  The logic for that
has proven to be slightly subtle; I will split it out into its own separate
diff.

Reviewed By: wez

Differential Revision: D4351072

fbshipit-source-id: 7a9d81cbd226c9662a79a2f2ceda82fe2651f312
2017-01-17 15:03:20 -08:00
Adam Simpkins
3e41ecaa26 Remove FileInode::parentInode_
Summary:
This member variable was not updated properly when files were renamed.
InodeBase now tracks our parent properly, so we don't need our own copy.

This does still call getParentBuggy() (which does not perform proper locking)
in a couple places for performing overlay operations.  We'll need to fix this
later when addressing other overlay concurrency handling issues.

Reviewed By: bolinfest

Differential Revision: D4348481

fbshipit-source-id: 19c1ffced6f63e1ff041d0bab2363fecdb93d5a3
2016-12-22 15:36:29 -08:00
Adam Simpkins
9ba08b9d1e Update FileData to store a pointer to its FileInode
Summary:
Have FileData objects store a pointer to the FileInode that owns them, rather
than just to the EdenMount.

FileData objects still store a direct pointer to their FileInode's mutex_ and
entry_.  It's potentially worth just accessing these through inode_ in the
future.

Reviewed By: bolinfest

Differential Revision: D4348103

fbshipit-source-id: 1f8497979bfc89c6a192ca0195209335db0d911c
2016-12-22 15:36:29 -08:00
Adam Simpkins
5b346bbff2 update code to use InodeMap
Summary:
This updates all of the eden code to use the new InodeMap class.  This replaces
the InodeNameManager class and the unordered_map previously stored in the
EdenDispatcher.

Reviewed By: bolinfest

Differential Revision: D4325750

fbshipit-source-id: d80ae7581ba79ca2b63155e184995a3e83e85dc1
2016-12-22 15:36:29 -08:00
Adam Simpkins
007726931b add a new InodeError class
Summary:
InodeError is a subclass of std::system_error that accepts an InodePtr to the
inode that it refers to.  This makes it easier to construct error objects that
retain information about the inode they refer to.

InodeError also avoids computing the inode path until the error message is
actually needed.  This should make it less expensive in cases where errors are
thrown and handled internally without ever using the human-readable error
message.  It is possible that the file may have been renamed or unlinked by the
time the error message is computed.  However, this race condition might still
exist even if we computed the path at the time when the error is constructed.
getLogPath() will construct a usable human-readable string even if the file has
been unlinked.

Reviewed By: wez

Differential Revision: D4325043

fbshipit-source-id: c9683a80b022f281ca4583a9b7f73b15277335bb
2016-12-14 15:36:11 -08:00
Adam Simpkins
c81ee4c997 update getSha1ForBlob() to return the Hash by value
Summary:
Hash objects are small enough (20 bytes) that it isn't worth allocating them on
the heap.  This updates LocalStore::getSha1ForBlob() to return a
folly::Optional<Hash>, and ObjectStore::getSha1ForBlob() to return a plain
Hash.

Reviewed By: bolinfest

Differential Revision: D4298162

fbshipit-source-id: 9cf54f2997ba8c3b2346db315a2aca41e580b078
2016-12-12 17:50:36 -08:00
Adam Simpkins
89fb0f811b add InodePtr, TreeInodePtr, and FileInodePtr type names
Summary:
Define InodePtr, TreeInodePtr, and FileInodePtr as aliases for std::shared_ptr
of the underlying inode type.  This also updates all of the code to use these
new type names.

This will make it easier swap out std::shared_ptr with a custom pointer type in
the future.  (I believe we will need a custom type in the future so that we
can have more precise control of the reference counting so we can load and
unload Inode objects on demand.  std::shared_ptr::unique() doesn't quite
provide the flexibility we need, and is also being deprecated in C++17.)

Reviewed By: bolinfest

Differential Revision: D4297791

fbshipit-source-id: 1080945649290e676f62689592159f1166159b20
2016-12-12 17:50:35 -08:00
Adam Simpkins
e7b2e8bd52 update InodeBase to track its path
Summary:
This updates the InodeBase code to track its location in the filesystem.
Since we do not support hard links, each inode has a single path where it
exists.

Tracking this data allows us to implement getPath() as a method of InodeBase.

This code is not really complete yet, but it seems worth getting the current
code in as-is.  The location data is not updated properly on unlinks or
renames, but it looks like the existing InodeNameManager code does not get
updated either.  I am working on some additional refactoring of inode object
management, and it will be easier to come back and fix the unlink and rename
handling after this refactoring is further along.

Reviewed By: bolinfest

Differential Revision: D4297591

fbshipit-source-id: 82ceb326e4f9c376f627b1d8f49bb7db3cfc2b0b
2016-12-12 17:50:35 -08:00
Adam Simpkins
da04640287 move InodeBase from eden/fuse to eden/fs/inodes
Summary:
Move the InodeBase class from the lower-level fusell code up to the
eden/fs/inodes layer, now that everything else that uses it is in
eden/fs/inodes.

I plan to start changing the ownership model of inode objects a bit, and this
will allow the InodeBase class to interact with EdenDispatcher and other
classes in eden/fs/inodes.

Reviewed By: bolinfest

Differential Revision: D4283392

fbshipit-source-id: 9e1d6fb81dc223f905847cbe8d165a40ad0aca4d
2016-12-07 20:05:20 -08:00
Adam Simpkins
f9a99e0ba1 remove fusell::DirInode and fusell::FileInode
Summary:
Now that the EdenDispatcher class has been moved into eden/fs, we no longer
need the distinction between TreeInode and fusell::DirInode, and FileInode and
fusell::FileInode.

This diff deletes the fusell versions of these classes, and updates all of the
code to always directly use TreeInode and FileInode.  This allows us to get rid
of the remaining dynamic_casts between these pairs of classes.

Reviewed By: bolinfest

Differential Revision: D4257165

fbshipit-source-id: e2b6f328b9605ca0e2882f5cf7a3983fb4470cdf
2016-12-01 17:52:31 -08:00
Adam Simpkins
0e613bd96b rename TreeEntryFileInode to FileInode
Summary:
Rename TreeEntryFileInode to FileInode, and TreeEntryFileHandle to FileHandle.
These class names were long and awkward.

It's slightly unfortunate that we now have classes named both
eden::fuse::FileInode and eden::fuse::fusell::FileInode, but I don't believe
this should cause any major problems.  If we want to eliminate these name
collisions in the future I would advocate for renaming the fusell versions to
something like "FileInodeIface".

Reviewed By: bolinfest

Differential Revision: D4217909

fbshipit-source-id: 899672a318d7ae39595f2c18e171f8fd6cebedc6
2016-11-30 15:49:13 -08:00