Generalize safe host-to-isolated rename migration

This commit is contained in:
ms2k 2026-07-29 22:20:04 +09:00
commit 35ab7f17c0

View file

@ -745,14 +745,27 @@ error behavior. An isolated-to-host rename, cross-backing hard link,
host-to-isolated class returns `EXDEV` before either backing is changed.
`RENAME_WHITEOUT` returns `EOPNOTSUPP` without mutation.
A plain or `RENAME_NOREPLACE` host-to-isolated directory rename is qualified
only when the destination is absent and the complete source tree was created
through the current router instance. Every retained source identity must still
match, and every descendant must be a regular file or directory with supported
metadata. A writable description beneath the source must be read-only or
quiesced by a completed flush; any later mutation clears quiescence. Pinned
read-only file and directory descriptions remain attached to their original
host objects. Host mutation detected before quarantine refuses the rename.
A plain or `RENAME_NOREPLACE` host-to-isolated rename is qualified when the
complete source was created through the current router instance, every retained
source identity still matches, and the source has defined copy semantics. The
copyable set is single-link regular files, symbolic links, and trees containing
only those objects and directories with supported metadata. FIFOs are not
copyable because their live endpoint state is not observable through the FUSE
protocol. Hard-linked regular files, sockets, devices, and mounted trees are not
copyable.
The destination may be absent or, for a plain rename, an existing object that
the backing filesystem permits native rename to replace. `RENAME_NOREPLACE`
returns `EEXIST` for an existing destination. A directory may replace only an
empty directory; directory and nondirectory mismatches retain their native
errors.
A writable description beneath the source must be read-only or quiesced by a
completed flush; any later mutation clears quiescence. The gVisor composition
uses per-description handles for the routed mount, so closing a guest file
description releases its router handle even while pathname dentries remain
cached. Pinned read-only file and directory descriptions remain attached to
their original host objects. Host mutation detected before quarantine refuses
the rename.
A qualified rename is a durable migration transaction rather than a
cross-filesystem `rename(2)`. The router records and synchronizes intent before
@ -760,18 +773,21 @@ renaming the source to a reserved same-backing host quarantine. It synchronizes
that parent, copies through descriptor-confined traversal into a reserved
isolated staging tree, verifies the staged tree and quarantined source, and
synchronizes the isolated tree before publishing it with a same-backing rename.
Only a qualified isolated destination permits deletion of the exact
quarantined tree. The router synchronizes the host parent before clearing
intent.
For replacement, it first moves the exact old isolated destination to a
same-backing backup and synchronizes the destination parent. Only a qualified
isolated destination permits deletion of the exact quarantined tree and backup.
The router synchronizes both affected parents before clearing intent.
The affected paths do not admit new observations while the transaction is
unresolved. Startup reconciles every retained intent before publishing router
readiness. Recovery exposes either the complete host source or the qualified
isolated destination; partial staging and changed quarantine remain
unpublished and fail closed. The transaction never copies isolated bytes into
the host backing. Its success refines the sandbox namespace to one complete
endpoint but does not promise cross-filesystem inode identity or atomic
observation by host processes that bypass FUSE.
unpublished and fail closed. Before publication, recovery restores an exact old
destination from its backup; after publication, it retains only the qualified
new destination. The transaction never copies isolated bytes into the host
backing. Its success refines the sandbox namespace to one complete endpoint but
does not promise cross-filesystem inode identity or atomic observation by host
processes that bypass FUSE.
All other cross-backing renames retain `EXDEV` behavior. Applications may react
to `EXDEV` with their own visible copy and unlink operations.