write: new-file publish uses a hard link, so it fails on exFAT (EISDIR) with no fallback #4981
Replies: 2 comments
会话 / 历史(「write: new-file publish uses a hard link, so it fails on exFAT (EISDIR) with no fallback」)会话数据一般在用户目录下的 dsh 数据路径(随版本可能是
不要只拷单个 |
|
Confirmed on master (c291e79): the createIfAbsent path still publishes via hard link with no fallback. packages/fs/fs-local/src/fsio.ts:616-621 if (createIfAbsent !== undefined) {
try { await linkFile(tempPath, absolutePath) }
catch (error) { await throwGuardedCreateFailure(error, absolutePath, ...) }
}
Your proposed patch is the right shape and I endorse it: on a hard-link-unsupported error code Workaround until fixed: keep new-file writes off exFAT volumes (overwrite/edit continue to work), or apply the local |
Uh oh!
There was an error while loading. Please reload this page.
Labels:
bugfilesystemwindowsSummary
writeFileAtomicpublishes a new file with a hard link. exFAT has no hard-linksupport, so on any exFAT volume — the common case for removable drives and cross-OS
project shares — the
writetool cannot create a single new file. Overwriting an existingfile works, which makes the failure look arbitrary.
Location
packages/fs/fs-local/src/fsio.ts:546staging dir.<name>.<pid>.<uuid>.tmpdir:578-583new-file path:await linkFile(tempPath, absolutePath)→ catch →throwGuardedCreateFailure:584-594replace path:ReplaceFileW, withrenamefallback → works on exFATMeasured on this machine (workspace volume = exFAT, harness-home volume = NTFS)
writecreate new file (on the exFAT volume)EISDIRwriteoverwrite a read file (on the exFAT volume)editexisting file (on the exFAT volume)fs.link(on the exFAT volume)EISDIR: illegal operation on a directory, link '<…>.tmpdir\a.tmp' -> '<target>'open(target,'wx')twice (on the exFAT volume)EEXIST, first file untouchedThe errno is itself a hazard: a hard-link-less volume answers
link()asEISDIR("illegal operation on a directory"), which reads like a path/type bug. In
a recorded runaway session the model concluded from it that its own temp filename was malformed and
burned many steps on that theory.
Why the obvious fallback is wrong
Falling back to plain
renamebreaks the contract of this code path:createIfAbsentexists to guarantee no-replace, and
renameover an existing target silently clobbersit (measured: target content
A→B).Proposed patch (in use locally, 144 tests +
tsc -bclean)with
Semantics preserved: a real collision is still
EEXIST→FS_NOT_OBSERVED; a directorytarget is still
FS_NOT_REGULAR_FILE(thewxclaim fails and the existing inspectionclassifies it). Only regression vs the link path: a brand-new file may be observed empty
for an instant.
EPERM/EACCES-style permission faults keep their old classificationbecause the failed claim falls back into
throwGuardedCreateFailure.Suggested tests
linkFileto throwEISDIR; assert the file is created and contains the content.FS_NOT_OBSERVEDand theexisting bytes survive.
FS_NOT_REGULAR_FILE.CI tmpdirs are usually NTFS/ext4, so case 1 needs the mock — the existing suite already
uses
internals.linkFile, so the seam exists.All reactions