Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs.copyFile fails with permission denied when source is read-only #3117

Closed
RaisinTen opened this issue Feb 23, 2021 · 3 comments
Closed

fs.copyFile fails with permission denied when source is read-only #3117

RaisinTen opened this issue Feb 23, 2021 · 3 comments
Labels

Comments

@RaisinTen
Copy link
Contributor

See: nodejs/node#37284
cc @kakaroto

@bnoordhuis
Copy link
Member

Platform: Linux 4.19.0-11-amd64 #1 SMP Debian 4.19.146-1 (2020-09-17) x86_64 Linux

See torvalds/linux@6f9718f - it's a cephfs bug that was fixed (well, mitigated) in Linux 4.20. There's no workaround but I'll open a pull request with a fallback.

bnoordhuis added a commit to bnoordhuis/libuv that referenced this issue Feb 28, 2021
Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from
command when it shouldn't. Fall back to a regular file copy.

Fixes: libuv#3117
Refs: torvalds/linux@6f9718f
@kakaroto
Copy link

kakaroto commented Mar 9, 2021

Nice find! Can't wait to test it out. Not sure why Node 12.18.4 works (it might be something else behind this, since NFS also seemed affected by the bug I found), but I have high hopes that this would fix it too. Will give that a try as soon as it's available in an update for me to test with.
Thanks for finding/implementing the workaround so quickly 👍

@kakaroto
Copy link

I see that this fix was released as part of libuv 1.42.0 which was included in node 16.7.0 released last week.
I've tested my previous test case with node 16.7.0 and unfortunately the issue is still there.

Note that I was also able to reproduce a similar problem with a cifs mount (which also affects 12.18.x) and which also still happens in 16.7.0. Hopefully, with cifs (SMB mount), it should make it much easier to test and reproduce the issue on dev environments.

docker run --rm -it -v /cifs-mount/tmp:/mount node:12.19.0-alpine /bin/sh

su - node
echo foo > /tmp/foo
chmod -w /tmp/foo
cat <<EOF > test.js
  const fs = require("fs");
  fs.copyFileSync("/tmp/foo", "/mount/bar");
EOF

rm -f /mount/bar
node test.js
exit
exit

(Note that running the same commands as above but without the chmod -w on the input file does not result in any errors.)

The difference between cifs and cephfs mounts in the behavior is that cephfs doesn't have the issue on node 12.18.4 (libuv 1.38.0), but has the problem on node 12.19.0 (libuv 1.39.0), while cifs has the problem on both versions. The other difference is with cifs, the target file actually gets created (but empty), despite the fact that it throws the EPERM error, while on cephfs, it will not create the target file at all.
Note that I tested/confirmed the cephfs behavior on Linux 4.19.0-13 (Linux 4.19.0-13-cloud-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64 GNU/Linux) while I tested/confirmed the cifs behavior on Linux 5.0.16-100 (Linux 5.0.16-100.fc28.x86_64 #1 SMP Tue May 14 18:22:28 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux)

JeffroMF pushed a commit to JeffroMF/libuv that referenced this issue May 16, 2022
Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from
command when it shouldn't. Fall back to a regular file copy.

Fixes: libuv#3117
Refs: torvalds/linux@6f9718f
PR-URL: libuv#3123
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Varstahl added a commit to Varstahl/libuv that referenced this issue Mar 10, 2023
Trying to copy a read-only file onto a ceph-fuse filesystem fails,
returning an `EACCES` error. This happens when the destination
doesn't exist yet, and a new file is created.

By checking that the error matches, and that the destination file
is empty, we can fix this issue while waiting for a proper Ceph
fix to be upstreamed.

Fixes: libuv#3919
Refs: nodejs/node#37284
Refs: libuv#3117
Refs: libuv#3322
bnoordhuis pushed a commit that referenced this issue Mar 12, 2023
Trying to copy a read-only file onto a ceph-fuse filesystem fails,
returning an `EACCES` error. This happens when the destination
doesn't exist yet, and a new file is created.

By checking that the error matches, and that the destination file
is empty, we can fix this issue while waiting for a proper Ceph
fix to be upstreamed.

Fixes: #3919
Refs: nodejs/node#37284
Refs: #3117
Refs: #3322
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants