unix: add UV_FS_COPYFILE_FICLONE support#1491
Conversation
|
Why adding this behind flag? Why don't try the |
|
I've been using https://unix.stackexchange.com/questions/80351/why-is-cp-reflink-auto-not-the-default-behaviour as the motivation not to do it by default. I don't have really strong feelings one way or the other. However, if we do copy-on-write by default, then there should probably be a flag to opt out of it. |
|
I'm fine either way. Just wanted to note that we probably want a consistent behavior between platforms. Is |
bnoordhuis
left a comment
There was a problem hiding this comment.
Aside: we made a mistake in the previous PR: we don't check the flags, leaving the caller with no good way to check if libuv supports a particular flag.
We should have been doing this:
if (req->flags & ~UV_FS_COPYFILE_EXCL) {
errno = EINVAL;
return -1;
}| if (ioctl(destfd, FICLONE, srcfd) == -1) | ||
| err = -errno; | ||
|
|
||
| if (err != UV_EXDEV) |
There was a problem hiding this comment.
err can be uninitialized at this point, can't it?
| goto out; | ||
| } | ||
|
|
||
| #ifdef FICLONE |
There was a problem hiding this comment.
FICLONE isn't visible unless you (edit: struck out obsolete comment)#include <linux/fs.h> - and even then it won't be in many mainstream distros' /usr/include for a while.
@santigimeno, I'm not 100% certain, but the
Opened #1493
@bnoordhuis thoughts on moving this forward? Should I try to? I've seen |
It looks you're right :) |
|
@cjihrig You could try defining it yourself. Untested but if you #ifndef FICLONE
#define FICLONE _IOW(0x94, 9, int)
#endifJust hard-coding the value won't work because ioctls can have different values on different platforms. |
5926ae0 to
6a8137d
Compare
|
@bnoordhuis updated to try your idea. I verified that the |
bnoordhuis
left a comment
There was a problem hiding this comment.
Changes themselves LGTM.
Would it be better to return an error if the ioctl is not supported, in case you really want copy-on-write semantics and not just a copy?
It's easy for the caller to retry without the flag if copy-on-write is merely an optimization and a plain copy is acceptable.
I originally wanted it to "just work" but after testing the thing, I'm thinking that might be a good idea. |
It seems like It would be nice if we could pass this flag when |
|
@LinusU interesting. That flag isn't documented at https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/copyfile.3.html, which is the first Google search result for |
|
Yeah, I think that is an old manpage, this is from the latest beta of High Sierra: Notice that the url starts with |
|
Ha I did notice I'll definitely look into it. |
|
Hehe :) Awesome! Let me know if there is anything I can do to help 🙌 |
|
Rebase is simple: diff --cc test/test-fs-copyfile.c
index 460c1dc6,874a52af..00000000
--- a/test/test-fs-copyfile.c
+++ b/test/test-fs-copyfile.c
@@@ -120,12 -119,11 +120,18 @@@ TEST_IMPL(fs_copyfile)
ASSERT(r == 0);
handle_result(&req);
+ /* Copies a file of size zero. */
+ unlink(dst);
+ touch_file(src, 0);
+ r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL);
+ ASSERT(r == 0);
+ handle_result(&req);
++
+ /* Copies file using UV_FS_COPYFILE_FICLONE. */
+ unlink(dst);
+ r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE, NULL);
+ ASSERT(r == 0);
+ handle_result(&req);
/* Copies file synchronously. Overwrites existing file. */
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
@@@ -155,9 -147,9 +161,9 @@@
unlink(dst);
r = uv_fs_copyfile(loop, &req, fixture, dst, 0, handle_result);
ASSERT(r == 0);
- ASSERT(result_check_count == 5);
- uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(result_check_count == 4);
+ ASSERT(result_check_count == 6);
+ uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(result_check_count == 5);
++ ASSERT(result_check_count == 7);
unlink(dst); /* Cleanup */
return 0; |
|
Hi @cjihrig |
535b525 to
ded9716
Compare
|
I've rebased this PR. Here is a passing CI: https://ci.nodejs.org/view/libuv/job/libuv-test-commit/739/ Given these comments:
and I think it makes sense to move forward with |
UV_FS_COPYFILE_FICLONE attemps to use copy-on-write semantics in uv_fs_copyfile(). If CoW is not available, it falls back to a normal copy operation. Refs: libuv#1465 PR-URL: libuv#1491 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
UV_FS_COPYFILE_FICLONE_FORCE attempts to use copy-on-write semantics in uv_fs_copyfile(). If CoW is not available, an error is returned. Refs: libuv#1465 Refs: libuv#1491 PR-URL: libuv#1768 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Refs: #1465