Commit Graph

4 Commits

Author SHA1 Message Date
Xavier Deguillard
754d132783 Back out "prjfs: handle concurrent file/directory removal"
Summary: Something is wrong with this which causes Unity to freak out.

Reviewed By: fanzeyi

Differential Revision: D25453230

fbshipit-source-id: 89f61fd97817403fa65071ddac022a226b775e53
2020-12-10 07:42:38 -08:00
Xavier Deguillard
2bfdf6f481 prjfs: handle concurrent file/directory removal
Summary:
A while back, we saw that concurrent directory creation would lead to EdenFS
being confused and failing to record some of the created directories. This then
caused EdenFS to no longer being in sync with what was on disk. To handle this
case, we've had to manually creating these directories recursively.

What I didn't realize at the time was that these concurrent notifications could
also happen on removal this time, and if a directory removal notification wins
the race against the removal of its last children, that directory wouldn't be
removed and EdenFS would once again be confused about the state of the
repository.

Fixing this is a bit trickier than directory creation as it's more racier.
Consider a directory that is being removed, and then immediately recreated with
a file in it in a different process. The naive approach of simply force
removing all of the children of a directory when handling the removal
notification would clash with the file creation. We could argue that nobody
should be doing this, but there would be an unhandled race, and thus a bug
where data would potentially be lost[0].

We can however fix this bug slightly differently. For file/directory removal,
we can actually hook onto the pre-callback, ie: one that happens before the
file/directory is no longer visible on disk. This inherently eliminate the race
altogether as the callback will be guaranteed to run when none of its children
are present, and if a race happens with a file creation in it, we can simply
fail the removal properly.

The only tricky bit is for the renaming logic, as renaming a file is logically
a removal followed by a creation. For that reason, I've moved part of the
renaming bits to the pre-callback too.

In theory, this change may negatively affect workloads that do concurrent
directory removal as the duration during which a file/directory is visible
ondisk now includes the EdenFS callback while it didn't before. Such workflows
should be fairly rare and/or redirected to avoid EdenFS altogether if
performance matters.

[0]: This left-over file that EdenFS wouldn't be aware of would also later
cause the checkout code to fail due to invalidation failures triggered when
trying to invalidate that directory. This would be fairly hard to debug.

Reviewed By: fanzeyi

Differential Revision: D25112381

fbshipit-source-id: 9300499ce872ad93d0a687f0e61b7e2a9caf9556
2020-12-04 14:25:44 -08:00
Xavier Deguillard
4626f30206 utils: actually return an HRESULT from exceptionToHResult
Summary: These errors are Win32 errors, we need to wrap them into a HRESULT.

Reviewed By: chadaustin

Differential Revision: D24809646

fbshipit-source-id: 9f42b9d0c43474967dc26cb2c14cbee463768b79
2020-11-10 09:59:25 -08:00
Wez Furlong
745d047762 edenfs: move WinError to eden/fs/utils
Summary: This resolves a dependency cycle introduced in D23037325 (f4f159537f) and D23480435 (34821976e0)

Reviewed By: xavierd

Differential Revision: D23735176

fbshipit-source-id: a4849d512e4181afbb007d7e850aadf092c6eb90
2020-09-17 09:08:58 -07:00