pub fn scan(root: &Path) -> LeanResult<Scan>Expand description
Walk the workspace. Skips the state dir, the control namespace and symlinks (v1 non-goal, as the tier manifest’s).
What the syncer may not read (EACCES or EPERM) is HELD (Scan::held),
never skipped: a directory it may not list, an entry it may not lstat.
classify reads a path missing from two scans as the agent’s delete,
and the barrier then publishes the deletion and deletes the object,
so a skipped directory would cost every file under it; a held one
costs nothing, because classify neither uploads nor deletes a path
at or under it, and Scan::present keeps it in prev_scan. The rest
of the tree publishes. The walk used to FAIL instead (c24beeb7), and
then one 0700 directory made by an app running as a uid other than
the CR’s stopped every publish in the workspace until it was readable.
A path’s key is its names, byte for byte, so the barrier opens the
file it scanned. A name that is not UTF-8 has no such key and is held
too (L-141); a \ in a name is a byte like any other (L-142). Either
used to give a key that named another file or none, and the upload’s
ENOENT failed every barrier in the workspace.
A name that is GONE by the time the walk stats it, or a directory gone
or replaced by the time the walk opens it, is absent from this scan
(NameError, L-144): the agent removed or moved it while the walk ran,
and the two-scan rule is what makes reading that as absence safe.
Every other error FAILS the walk, and with it the barrier: an EIO is not a standing condition the tree’s owner set, and an unreadable ROOT fails too (nothing could publish; the error names why).