diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-03-14 13:18:14 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-03-15 14:53:31 -0400 |
commit | ce33fddad0806f859ff7324527ee0525dd10455e (patch) | |
tree | 8223f829ce74a0e48e0ccb4500d01a02515f7d25 | |
parent | 70e43ee7be6ee8d1e8aa4b2984a72baa25709c2e (diff) |
test-copy: add a test shuffling bytes between normal files
I started looking into adding copy_file_range support, and discovered
that we can improve the way we call sendfile:
- sendfile(2) man page is missing an important bit: the number of bytes to
copy cannot be too big (SSIZE_MAX actually), and the description of EINVAL
return code does not mention this either,
- our implementation works but calls sendfile over and over with a small
size, which seems suboptimal.
First add a test which (under strace) can be used to see current behaviour.
-rw-r--r-- | src/test/test-copy.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/test/test-copy.c b/src/test/test-copy.c index ad57cb0202..622fba777d 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -24,6 +24,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "log.h" #include "macro.h" #include "mkdir.h" #include "path-util.h" @@ -39,6 +40,8 @@ static void test_copy_file(void) { size_t sz = 0; int fd; + log_info("%s", __func__); + fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); close(fd); @@ -66,6 +69,8 @@ static void test_copy_file_fd(void) { char text[] = "boohoo\nfoo\n\tbar\n"; char buf[64] = {0}; + log_info("%s", __func__); + in_fd = mkostemp_safe(in_fn, O_RDWR); assert_se(in_fd >= 0); out_fd = mkostemp_safe(out_fn, O_RDWR); @@ -91,6 +96,8 @@ static void test_copy_tree(void) { "link2", "dir1/file"); char **p, **link; + log_info("%s", __func__); + (void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL); (void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL); @@ -173,11 +180,50 @@ static void test_copy_bytes(void) { assert_se(r == -EBADF); } +static void test_copy_bytes_regular_file(const char *src, bool try_reflink) { + char fn2[] = "/tmp/test-copy-file-XXXXXX"; + char fn3[] = "/tmp/test-copy-file-XXXXXX"; + _cleanup_close_ int fd = -1, fd2 = -1, fd3 = -1; + int r; + struct stat buf, buf2, buf3; + + log_info("%s try_reflink=%s", __func__, yes_no(try_reflink)); + + fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY); + assert_se(fd >= 0); + + fd2 = mkostemp_safe(fn2, O_RDWR); + assert_se(fd2 >= 0); + + fd3 = mkostemp_safe(fn3, O_WRONLY); + assert_se(fd3 >= 0); + + r = copy_bytes(fd, fd2, (uint64_t) -1, try_reflink); + assert_se(r == 0); + + assert_se(lseek(fd2, 0, SEEK_SET) == 0); + + r = copy_bytes(fd2, fd3, (uint64_t) -1, try_reflink); + assert_se(r == 0); + + assert_se(fstat(fd, &buf) == 0); + assert_se(fstat(fd2, &buf2) == 0); + assert_se(fstat(fd3, &buf3) == 0); + + assert_se(buf.st_size == buf2.st_size); + assert_se(buf.st_size == buf3.st_size); + + unlink(fn2); + unlink(fn3); +} + int main(int argc, char *argv[]) { test_copy_file(); test_copy_file_fd(); test_copy_tree(); test_copy_bytes(); + test_copy_bytes_regular_file(argv[0], false); + test_copy_bytes_regular_file(argv[0], true); return 0; } |