Rather than checking whether a file exists before running an operation
and using the result of the first FS where it exists, always run
operations on the most recently added FS's first. If there's any error
other than missing file, return it immediately.
Also update CWD handling. The previous implementation attempted to
setCWD on all contained FS and then would use the CWD of the first
FS for getCWD, assuming they are all synced. This had a bunch of odd
behaviors:
- setCWD would fail but all FS up to the failure would have their CWD set. getCWD would then return the just set CWD, even though it "failed"
- Their CWD could get out of sync, so the CWD used by each FS wouldn't necessarily match the just set CWD
Fix this by keeping a CWD in OverlayFileSystem instead and pass the
already-absoluted path down into the contained FS. This has the downside
that any result needs to have the path overridden back to the original
(possibly relative) path, which is further complicated by certain
implementations needing to return a different path that *shouldn't* be
mapped.
Right now this is handled by only overriding the path if the returned
path was the one that was requested, but it would be nice to come up
with a better solution.
Depends on D121421
I think this will be easier to reason about if CWD is only updated on the first success inside a given call to OverlayFileSystem::setCurrentWorkingDirectory. (Note that different VFSes could be canonicalizing relative paths differently.)
I also wonder if, instead, we can just keep track of which FS currently has the canonical CWD:
Calls to getCurrentWorkingDirectory() would forward to overlays_begin()[IndexForCWD].getCurrentWorkingDirectory(). This way, the overlay inherits the CWD canonicalization of the first working FS (usually, BaseFS).