From 77ef3d3dafe422f89bbedb81a78494ee99765410 Mon Sep 17 00:00:00 2001 From: Varstahl Date: Fri, 10 Mar 2023 22:26:46 +0100 Subject: [PATCH] fs: fix ceph copy error truncating readonly files 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: https://github.com/libuv/libuv/issues/3919 Refs: https://github.com/nodejs/node/issues/37284 Refs: https://github.com/libuv/libuv/issues/3117 Refs: https://github.com/libuv/libuv/issues/3322 --- src/unix/fs.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index e1120cd775b..ea1d305f31d 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -1306,7 +1306,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { /* Truncate the file in case the destination already existed. */ if (ftruncate(dstfd, 0) != 0) { err = UV__ERR(errno); - goto out; + + /* ftruncate() on ceph-fuse fails with EACCES when the file is created + * with read only permissions. Since ftruncate() on a newly created + * file is a meaningless operation anyway, detect that condition + * and squelch the error. + */ + if (err != UV_EACCES) + goto out; + + if (dst_statsbuf.st_size > 0) + goto out; + + err = 0; } }