[LTP] [PATCH v3] syscalls: add new test for copy_file_range(2)
Jan Stancek
jstancek@redhat.com
Mon Apr 24 10:53:45 CEST 2017
----- Original Message -----
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <errno.h>
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +#include "linux_syscall_numbers.h"
> +
> +#define TEST_FILE_1 "copy_file_range_ltp01.txt"
> +#define TEST_FILE_2 "copy_file_range_ltp02.txt"
> +#define STR "abcdefghijklmnopqrstuvwxyz12345\n"
> +
> +static off_t len1 = 1; /* 1 */
> +static off_t len2; /* stat.st_size */
> +static off_t len3; /* stat.st_size - 1 */
> +static off_t page_size1; /* pagesize - 1 */
> +static off_t page_size2; /* pagesize */
> +static off_t page_size3; /* pagesize + 1 */
> +
> +static struct tcase {
> + off_t *off_in;
> + off_t *off_out;
> + off_t *len;
> +} tcases[] = {
> + {NULL, NULL, &len1}, /* NULL, NULL, 1 */
> + {NULL, NULL, &len2}, /* NULL, NULL, stat.st_size */
> + {&len3, &len3, &len1}, /* stat.st_size - 1, stat.st_size - 1, 1 */
> + {&page_size1, &page_size1, &page_size1}, /* pagesize - 1, pagesize - 1,
> pagesize - 1 */
> + {&page_size2, &page_size2, &page_size2}, /* pagesize, pagesize,
> pagesize */
> + {&page_size3, &page_size3, &page_size3}, /* pagesize + 1, pagesize + 1,
> pagesize + 1 */
> +};
Hi,
These variables names are a bit confusing. But larger problem is
that the values are not stable between iterations. Try:
$ ./copy_file_range01 -i 5
^^ this hangs for me.
> +static void copy_file_range_verify(unsigned int i)
> +{
> + int fd_in, fd_out;
> + off_t off_in_ori = 0;
> + off_t off_out_ori = 0;
> +
> + struct tcase *tc = &tcases[i];
> + off_t len = *(tc->len);
> +
> + if (tc->off_in) {
> + /*
> + * off_in/off_out will be changed if it is not NULL,
> + * here save the original value first
> + */
> + off_in_ori = *(tc->off_in);
> + off_out_ori = *(tc->off_out);
> + }
> + off_t len_ori = len;
> +
> + fd_in = SAFE_OPEN(TEST_FILE_1, O_RDONLY);
> + fd_out = SAFE_OPEN(TEST_FILE_2, O_CREAT | O_WRONLY | O_TRUNC, 0644);
> +
> + /*
> + * copy_file_range() will return the number of bytes copied between files.
> + * This could be less than the length originally requested.
> + */
> + do {
> + TEST(tst_syscall(__NR_copy_file_range, fd_in, tc->off_in, fd_out,
> tc->off_out, len, 0));
> + if (TEST_RETURN == -1) {
> + tst_res(TFAIL | TTERRNO, "copy_file_range() failed");
> + SAFE_CLOSE(fd_in);
> + SAFE_CLOSE(fd_out);
> + return;
> + }
> +
> + len -= TEST_RETURN;
> + } while (len > 0);
> +
> + /* Compare these two file contents */
> + FILE *fp1, *fp2;
> + int ch1, ch2;
> + off_t count = 0;
> +
> + fp1 = SAFE_FOPEN(TEST_FILE_1, "r");
> + if (fseek(fp1, off_in_ori, SEEK_SET))
> + tst_brk(TBROK | TERRNO, "fseek() failed");
> +
> + fp2 = SAFE_FOPEN(TEST_FILE_2, "r");
> + if (fseek(fp2, off_out_ori, SEEK_SET))
> + tst_brk(TBROK | TERRNO, "fseek() failed");
> +
> + do {
> + ch1 = getc(fp1);
> + ch2 = getc(fp2);
> + count++;
> + } while ((count < len_ori) && (ch1 == ch2));
> +
> + if (ch1 == ch2) {
> + tst_res(TPASS, "file contents match %ld bytes", len_ori);
> + /*
> + * If off_in is NULL, the file offset is adjusted by the number of bytes
> copied.
> + * If off_in is not NULL, the file offset of fd_in is not changed, but
> off_in is
> + * adjusted appropriately.
> + */
> + if (!tc->off_in) {
> + if (SAFE_LSEEK(fd_in, 0, SEEK_CUR) == SAFE_LSEEK(fd_out, 0, SEEK_CUR))
> + tst_res(TPASS, "file offset are same");
> + else
> + tst_res(TFAIL, "file offset are not same");
> + } else {
> + if (*(tc->off_in) == (off_in_ori + len_ori))
> + tst_res(TPASS, "file off_in changed correctly");
What about off_out?
Regards,
Jan
More information about the ltp
mailing list