node-graceful-fs: Error: EPERM: operation not permitted, rename '...' -> '...'
Last graceful-fs 4.1.11
causes Error: EPERM: operation not permitted, rename '...' -> '...'
on Windows platform.
My investigation:
It happens with session-file-store
, that has dependency fs-extra
, that has dependency graceful-fs
. Problem occurs when user make more parallel HTTP calls to server. With the previous version graceful-fs 4.1.10
it works fine.
All start works without errors when I rollback the code in graceful-fs 4.1.11
-> polyfills.js
-> line 101
from:
setTimeout(function() {
fs.stat(to, function (stater, st) {
if (stater && stater.code === "ENOENT")
fs$rename(from, to, CB);
else
cb(er)
})
}, backoff)
to previous
setTimeout(function() {
fs$rename(from, to, CB);
}, backoff)
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 4
- Comments: 28
Commits related to this issue
- switch session-file-store --> connect-loki - fixes EPERM problem on windows - see https://github.com/isaacs/node-graceful-fs/issues/104 — committed to yortus/routist by yortus 6 years ago
- Try to fix EPERM See https://github.com/isaacs/node-graceful-fs/issues/104 — committed to mifi/node-graceful-fs by mifi 4 years ago
@ma-zal for your information, I just started using connect-loki and it’s working great. Almost a drop in replacement for session-file-store. It persists data to a single json file.
The problem is that
fs.rename
wrongly callsMoveFileEx
when it ought to be calling NtSetInformationFile with the argumentFILE_RENAME_INFORMATION
with the flagsFILE_RENAME_REPLACE_IF_EXISTS | FILE_RENAME_POSIX_SEMANTICS
.I suspect that the failure to request
FILE_RENAME_POSIX_SEMANTICS
is the root of the problem.fs.rename
assumes that rename() is atomic per the POSIX (Linux) standard but is failing to ask Windows to provide said semantics.@about-code Yes, I can confirm. I was encountering it while using express-session and session-file-store. After doing a lot of research, I now believe that it’s because the rename operation is requested while the file is still open and in use.
Pretty sure this is relevant
This also happens in my use case, where I am using
express
andsocket.io
, where the session is shared to the sockets.@about-code I believe I have confirmed the root of the problem. You can cause a EPERM issue when multiple write operations are issued concurrently on a Windows system. The reason why this isn’t an issue on Unix like systems is due to the nature of the POSIX rename, which simply replaces the file. On windows I guess it’s a little more complicated.
I believe this is not an issue with graceful-fs, but write-file-atomic, which should probably serialize write operations to the same file. I’ll make a PR for that as well. Do you think a separate issue should be opened on write-file-atomic? I’d appreciate your input! Write-file-atomic has a LOT of dependents and I’d imagine this issue could negatively affect all Windows users of these packages.