[LTP] [PATCH v2] syscalls/copy_file_range: add/restructured tests

Li Wang liwang@redhat.com
Wed Apr 24 15:13:11 CEST 2019


Hi Christian,

Glad to see more tests for copy_file_range, some comments in below.

On Tue, Apr 23, 2019 at 8:52 PM Christian Amann <camann@suse.com> wrote:

> The following tests are run for the syscall itself,
> as well as the glibc implementation.
>
> copy_file_range01:
>         restructured testcase, removed unnecessary code,
>         improved readability and shortened output (only
>         failures get printed now).
>
> copy_file_range02:
>         add testcases which test basic functions and error
>         handling of the syscall.
>
> copy_file_range03:
>         add testcase to check if this operation updates
>         timestamps accordingly.
>
> Signed-off-by: Christian Amann <camann@suse.com>
> ---
>  configure.ac                                       |   1 +
>  m4/ltp-copy_file_range.m4                          |   7 +
>  runtest/syscalls                                   |   2 +
>  .../kernel/syscalls/copy_file_range/.gitignore     |   2 +
>  .../syscalls/copy_file_range/copy_file_range.h     |  56 +++++
>  .../syscalls/copy_file_range/copy_file_range01.c   | 232
> +++++++++++----------
>  .../syscalls/copy_file_range/copy_file_range02.c   | 125 +++++++++++
>  .../syscalls/copy_file_range/copy_file_range03.c   |  81 +++++++
>  8 files changed, 399 insertions(+), 107 deletions(-)
>  create mode 100644 m4/ltp-copy_file_range.m4
>  create mode 100644
> testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>  create mode 100644
> testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>  create mode 100644
> testcases/kernel/syscalls/copy_file_range/copy_file_range03.c
>
> diff --git a/configure.ac b/configure.ac
> index fad8f8396..3fec68ede 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -197,6 +197,7 @@ LTP_CHECK_BUILTIN_CLEAR_CACHE
>  LTP_CHECK_CAPABILITY_SUPPORT
>  LTP_CHECK_CC_WARN_OLDSTYLE
>  LTP_CHECK_CLONE_SUPPORTS_7_ARGS
> +LTP_CHECK_COPY_FILE_RANGE
>  LTP_CHECK_CRYPTO
>  LTP_CHECK_FIDEDUPE
>  LTP_CHECK_FORTIFY_SOURCE
> diff --git a/m4/ltp-copy_file_range.m4 b/m4/ltp-copy_file_range.m4
> new file mode 100644
> index 000000000..2d87e8900
> --- /dev/null
> +++ b/m4/ltp-copy_file_range.m4
> @@ -0,0 +1,7 @@
> +dnl SPDX-License-Identifier: GPL-2.0-or-later
> +dnl Copyright (c) 2019 SUSE LLC
> +dnl Author: Christian Amann <camann@suse.com>
> +
> +AC_DEFUN([LTP_CHECK_COPY_FILE_RANGE],[
> +AC_CHECK_FUNCS(copy_file_range,,)
> +])
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 2b8ca719b..33a70ee17 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -1561,6 +1561,8 @@ memfd_create03 memfd_create03
>  memfd_create04 memfd_create04
>
>  copy_file_range01 copy_file_range01
> +copy_file_range02 copy_file_range02
> +copy_file_range03 copy_file_range03
>
>  statx01 statx01
>  statx02 statx02
> diff --git a/testcases/kernel/syscalls/copy_file_range/.gitignore
> b/testcases/kernel/syscalls/copy_file_range/.gitignore
> index 6807420ef..e9e35f60f 100644
> --- a/testcases/kernel/syscalls/copy_file_range/.gitignore
> +++ b/testcases/kernel/syscalls/copy_file_range/.gitignore
> @@ -1 +1,3 @@
>  /copy_file_range01
> +/copy_file_range02
> +/copy_file_range03
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> new file mode 100644
> index 000000000..74ad08b96
> --- /dev/null
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>

If we make use of SPDX-License-Identifier, the following contents of GPL
could be removed I think.



> +/*
> + * Copyright (c) 2019 SUSE LLC
> + * Author: Christian Amann <camann@suse.com>
> + */
> +
> +#ifndef __COPY_FILE_RANGE_H__
> +#define __COPY_FILE_RANGE_H__
> +
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include "lapi/syscalls.h"
> +
> +#define TEST_VARIANTS  2
> +
> +#define MNTPOINT       "mnt_point"
> +#define FILE_SRC_PATH   "file_src"
> +#define FILE_DEST_PATH  "file_dest"
> +#define FILE_RDONL_PATH "file_rdonl"
> +#define FILE_DIR_PATH  "file_dir"
> +#define FILE_MNTED_PATH        MNTPOINT"/file_mnted"
> +
> +#define CONTENT "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
> +
> +static void syscall_info(void)
> +{
> +       switch (tst_variant) {
> +       case 0:
> +               tst_res(TINFO, "Testing libc copy_file_range()");
> +               break;
> +       case 1:
> +               tst_res(TINFO, "Testing tst copy_file_range()");
> +       }
> +}
> +
> +static int sys_copy_file_range(int fd_in, loff_t *off_in,
> +               int fd_out, loff_t *off_out, size_t len, unsigned int
> flags)
> +{
> +       switch (tst_variant) {
> +
> +       case 0:
> +#ifdef HAVE_COPY_FILE_RANGE
> +               return copy_file_range(fd_in, off_in,
> +                               fd_out, off_out, len, flags);
> +#else
> +               tst_brk(TCONF, "libc copy_file_range() not supported!");
> +#endif
> +               break;
> +       case 1:
> +               return tst_syscall(__NR_copy_file_range, fd_in, off_in,
> fd_out,
> +                               off_out, len, flags);
> +       }
> +       return -1;
> +}
> +
> +#endif /* __COPY_FILE_RANGE_H__ */
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> index 61a6042d9..46e4997eb 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> @@ -1,5 +1,6 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> - * Copyright (c) Linux Test Project, 2017
> + * Copyright (c) Linux Test Project, 2019
>   *
>   * This program is free software;  you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
> @@ -12,55 +13,28 @@
>   * the GNU General Public License for more details.
>   */
>
> +/*
> + * This tests the fundamental functionalities of the copy_file_range
> + * syscall. It does so by copying the contents of one file into
> + * another using various different combinations for length and
> + * input/output offsets.
> + *
> + * After a copy is done this test checks if the contents of both files
> + * are equal at the given offsets. It is also inspected if the offsets
> + * of the file descriptors are advanced correctly.
> + */
> +
>  #define _GNU_SOURCE
> +
>  #include <stdio.h>
> -#include <errno.h>
>  #include <stdlib.h>
>  #include "tst_test.h"
>  #include "tst_safe_stdio.h"
> -#include "lapi/syscalls.h"
> -
> -#define TEST_FILE_1 "copy_file_range_ltp01.txt"
> -#define TEST_FILE_2 "copy_file_range_ltp02.txt"
> -#define STR "abcdefghijklmnopqrstuvwxyz12345\n"
> -
> -#define verbose 0
> -
> -static size_t *len_arr;
> -static loff_t **off_arr;
> -static int len_sz, off_sz;
> +#include "copy_file_range.h"
>
> -static void setup(void)
> -{
> -       int i, fd, page_size;
> -
> -       page_size = getpagesize();
> -
> -       fd = SAFE_OPEN(TEST_FILE_1, O_RDWR | O_CREAT, 0664);
> -       /* Writing page_size * 4 of data into test file */
> -       for (i = 0; i < (int)(page_size * 4); i++)
> -               SAFE_WRITE(1, fd, STR, strlen(STR));
> -       SAFE_CLOSE(fd);
> -
> -       len_sz = 4;
> -       len_arr = malloc(sizeof(size_t) * len_sz);
> -       len_arr[0] = 11;
> -       len_arr[1] = page_size - 1;
> -       len_arr[2] = page_size;
> -       len_arr[3] = page_size + 1;
> -
> -       off_sz = 6;
> -       off_arr = malloc(sizeof(loff_t *) * off_sz);
> -       for (i = 1; i < off_sz; i++)
> -               off_arr[i] = malloc(sizeof(loff_t));
> -
> -       off_arr[0] = NULL;
> -       *off_arr[1] = 0;
> -       *off_arr[2] = 17;
> -       *off_arr[3] = page_size - 1;
> -       *off_arr[4] = page_size;
> -       *off_arr[5] = page_size + 1;
> -}
> +static int page_size;
> +static int errcount, numcopies;
> +static int fd_in, fd_out;
>
>  static int check_file_content(const char *fname1, const char *fname2,
>         loff_t *off1, loff_t *off2, size_t len)
> @@ -90,52 +64,37 @@ static int check_file_content(const char *fname1,
> const char *fname2,
>  }
>
>  static int check_file_offset(const char *m, int fd, loff_t len,
> -       loff_t *off_ori, loff_t *off_after)
> +               loff_t *off_before, loff_t *off_after)
>  {
> +       loff_t fd_off = SAFE_LSEEK(fd, 0, SEEK_CUR);
>         int ret = 0;
>
> -       if (off_ori) {
> -               /* FD should stay untouched, and off_in/out is updated */
> -               loff_t fd_off = SAFE_LSEEK(fd, 0, SEEK_CUR);
> -
> -               if (fd_off == 0) {
> -                       if (verbose)
> -                               tst_res(TPASS, "%s FD offset unchanged",
> m);
> -               } else {
> -                       tst_res(TFAIL, "%s FD offset changed: %ld",
> +       if (off_before) {
> +               /*
> +                * copy_file_range offset is given:
> +                * - fd offset should stay 0,
> +                * - copy_file_range offset is updated
> +                */
> +               if (fd_off != 0) {
> +                       tst_res(TFAIL,
> +                               "%s fd offset unexpectedly changed: %ld",
>                                 m, (long)fd_off);
>                         ret = 1;
> -               }
>
> -               if (!off_after) {
> -                       tst_res(TFAIL, "%s offset is NULL", m);
> -                       ret = 1;
> -               }
> -
> -               if ((off_after) && (*off_ori + len == *off_after)) {
> -                       if (verbose) {
> -                               tst_res(TPASS, "%s offset advanced as"
> -                                       " expected: %ld", m,
> (long)*off_after);
> -                       }
> -               } else {
> +               } else if (*off_before + len != *off_after) {
>                         tst_res(TFAIL, "%s offset unexpected value: %ld",
>                                 m, (long)*off_after);
>                         ret = 1;
>                 }
> -       } else {
> -               /* FD offset is advanced by len */
> -               loff_t fd_off = SAFE_LSEEK(fd, 0, SEEK_CUR);
> -
> -               if (fd_off == len) {
> -                       if (verbose) {
> -                               tst_res(TPASS, "%s FD offset changed as"
> -                                       " expected: %ld", m, (long)fd_off);
> -                       }
> -               } else {
> -                       tst_res(TFAIL, "%s FD offset unexpected value:
> %ld",
> +       }
> +       /*
> +        * no copy_file_range offset given:
> +        * - fd offset advanced by length
> +        */
> +       else if (fd_off != len) {
> +               tst_res(TFAIL, "%s fd offset unexpected value: %ld",
>                                 m, (long)fd_off);
> -                       ret = 1;
> -               }
> +               ret = 1;
>         }
>
>         return ret;
> @@ -143,77 +102,136 @@ static int check_file_offset(const char *m, int fd,
> loff_t len,
>
>  static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>  {
> +       int ret;
>         size_t to_copy = len;
> -       int fd_in, fd_out, ret;
> -       loff_t *off_in_ori = off_in;
> -       loff_t *off_out_ori = off_out;
> -       loff_t off_in_copy;
> -       loff_t off_out_copy;
> +       loff_t off_in_value_copy, off_out_value_copy;
> +       loff_t *off_new_in  = &off_in_value_copy;
> +       loff_t *off_new_out = &off_out_value_copy;
>         char str_off_in[32], str_off_out[32];
>
>         if (off_in) {
> -               off_in_copy = *off_in;
> -               off_in = &off_in_copy;
> +               off_in_value_copy = *off_in;
>                 sprintf(str_off_in, "%ld", (long)*off_in);
>         } else {
> +               off_new_in = NULL;
>                 strcpy(str_off_in, "NULL");
>         }
>
>         if (off_out) {
> -               off_out_copy = *off_out;
> -               off_out = &off_out_copy;
> +               off_out_value_copy = *off_out;
>                 sprintf(str_off_out, "%ld", (long)*off_out);
>         } else {
> +               off_new_out = NULL;
>                 strcpy(str_off_out, "NULL");
>         }
>
> -       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, off_in,
> fd_out,
> -                       off_out, to_copy, 0));
> +               TEST(sys_copy_file_range(fd_in, off_new_in, fd_out,
> +                               off_new_out, to_copy, 0));
>                 if (TST_RET == -1) {
>                         tst_res(TFAIL | TTERRNO, "copy_file_range()
> failed");
> -                       SAFE_CLOSE(fd_in);
> -                       SAFE_CLOSE(fd_out);
> +                       errcount++;
>                         return;
>                 }
>
>                 to_copy -= TST_RET;
>         } while (to_copy > 0);
>
> -       ret = check_file_content(TEST_FILE_1, TEST_FILE_2,
> -               off_in_ori, off_out_ori, len);
> -       if (ret)
> +       ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
> +               off_in, off_out, len);
> +       if (ret) {
>                 tst_res(TFAIL, "file contents do not match");
> +               errcount++;
> +               return;
> +       }
>
> -       ret |= check_file_offset("(in)", fd_in, len, off_in_ori, off_in);
> -       ret |= check_file_offset("(out)", fd_out, len, off_out_ori,
> off_out);
> +       ret |= check_file_offset("(in)", fd_in, len, off_in, off_new_in);
> +       ret |= check_file_offset("(out)", fd_out, len, off_out,
> off_new_out);
> +
> +       if (ret != 0) {
> +               tst_res(TFAIL, "off_in: %s, off_out: %s, len: %ld",
> +                               str_off_in, str_off_out, (long)len);
> +               errcount++;
> +       }
> +}
>
> -       tst_res(ret == 0 ? TPASS : TFAIL, "off_in: %s, off_out: %s, len:
> %ld",
> -                       str_off_in, str_off_out, (long)len);
> +static void open_files(void)
> +{
> +       fd_in  = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY);
> +       fd_out = SAFE_OPEN(FILE_DEST_PATH, O_CREAT | O_WRONLY | O_TRUNC,
> 0644);
> +}
>
> -       SAFE_CLOSE(fd_in);
> -       SAFE_CLOSE(fd_out);
> +static void close_files(void)
> +{
> +       if (fd_out > 0)
> +               SAFE_CLOSE(fd_out);
> +       if (fd_in  > 0)
> +               SAFE_CLOSE(fd_in);
>  }
>
>  static void copy_file_range_verify(void)
>  {
>         int i, j, k;
>
> -       for (i = 0; i < len_sz; i++)
> -               for (j = 0; j < off_sz; j++)
> -                       for (k = 0; k < off_sz; k++)
> +       errcount = numcopies = 0;
> +       size_t len_arr[]        = {11, page_size-1, page_size,
> page_size+1};
> +       loff_t off_arr_values[] = {0, 17, page_size-1, page_size,
> page_size+1};
> +
> +       int num_offsets = ARRAY_SIZE(off_arr_values) + 1;
> +       loff_t *off_arr[num_offsets];
> +
> +       off_arr[0] = NULL;
> +       for (i = 1; i < num_offsets; i++)
> +               off_arr[i] = &off_arr_values[i-1];
> +
> +       /* Test all possible cobinations of given lengths and offsets */
> +       for (i = 0; i < (int)ARRAY_SIZE(len_arr); i++)
> +               for (j = 0; j < num_offsets; j++)
> +                       for (k = 0; k < num_offsets; k++) {
> +                               open_files();
>                                 test_one(len_arr[i], off_arr[j],
> off_arr[k]);
> +                               close_files();
> +                               numcopies++;
> +                       }
> +
> +       if (errcount == 0)
> +               tst_res(TPASS,
> +                       "copy_file_range completed all %d copy jobs
> successfully!",
> +                       numcopies);
> +       else
> +               tst_res(TINFO, "copy_file_range failed %d of %d copy
> jobs.",
> +                               errcount, numcopies);
> +}
> +
> +static void setup(void)
> +{
> +       int i, fd;
> +
> +       syscall_info();
> +
> +       page_size = getpagesize();
> +
> +       fd = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
> +       /* Writing page_size * 4 of data into test file */
> +       for (i = 0; i < (int)(page_size * 4); i++)
> +               SAFE_WRITE(1, fd, CONTENT, strlen(CONTENT));
> +       SAFE_CLOSE(fd);
> +}
> +
> +static void cleanup(void)
> +{
> +       close_files();
>  }
>
>  static struct tst_test test = {
>         .setup = setup,
> +       .cleanup = cleanup,
>         .needs_tmpdir = 1,
> +       .min_kver = "4.5",
>

No need to limit the minimal kernel version, since it will be skipped with
TCONF on an unsupported kernel. AFAIK, some distros also backport this
feature there, so we'd better cancel the kernel limitation.

        .test_all = copy_file_range_verify,
> +       .test_variants = TEST_VARIANTS,
>  };
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> new file mode 100644
> index 000000000..e1033609d
> --- /dev/null
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -0,0 +1,125 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 SUSE LLC
> + * Author: Christian Amann <camann@suse.com>
> + */
> +
> +/*
> + * Tests basic functions and error handling of the
> + * copy_file_range syscall
> + *
> + * 1) Copy contents of one file to another without
> + *    offset or anything special -> SUCCESS
> + * 2) Copy contents with offset in source file but keep
> + *    the length the same so that it exeeds EOF
> + *    -> SUCCESS, copy bytes until EOF
>

I'm thinking that should we split these functional test from the error
handling, which means the copy_file_range02.c only verify the syscall error
conditions.


> + * 3) Try to copy contents to file open as readonly
> + *    -> EBADF
> + * 4) Try to copy contents to file on different mounted
> + *    filesystem -> EXDEV
> + * 5) Try to copy contents to directory -> EISDIR
> + *
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <stdlib.h>
> +#include "tst_test.h"
> +#include "copy_file_range.h"
> +
> +#define MNTPOINT       "mnt_point"
> +#define FILE_RDONL_PATH "file_rdonl"
> +#define FILE_MNTED_PATH        MNTPOINT"/file_mnted"
>

These three macros have already defined in copy_file_range.h, so here is
redundant.

+
> +
> +static int fd_src;
> +static int fd_dest;
> +static int fd_rdonly;
> +static int fd_dir;
> +static int fd_mnted;
> +
> +static struct tcase {
> +       loff_t  off_in;
> +       loff_t  off_out;
> +       size_t  length;
> +       int     *copy_to_fd;
> +       int     bytes_copied;
> +       int     exp_err;
> +} tcases[] = {
> +       {0,  0, strlen(CONTENT),  &fd_dest,   strlen(CONTENT),    false},
> +       {0, 10, strlen(CONTENT),  &fd_dest,   strlen(CONTENT),    false},
> +       {10, 0, strlen(CONTENT),  &fd_dest,   strlen(CONTENT)-10, false},
> +       {0,  0, strlen(CONTENT),  &fd_rdonly, -1, EBADF},
> +       {0,  0, strlen(CONTENT),  &fd_mnted,  -1, EXDEV},
> +       {0,  0, strlen(CONTENT),  &fd_dir,    -1, EISDIR},
> +};
> +
> +static void verify_copy_file_range(unsigned int n)
> +{
> +       struct tcase *tc = &tcases[n];
> +
> +       loff_t off_in  = tc->off_in;
> +       loff_t off_out = tc->off_out;
> +
> +       TEST(sys_copy_file_range(fd_src, &off_in,
> +                           *tc->copy_to_fd, &off_out, tc->length, 0));
> +       if (tc->exp_err != TST_ERR) {
> +               tst_res(TFAIL,
> +                       "copy_file_range failed with %s, expected %s",
> +                       tst_strerrno(TST_ERR), tst_strerrno(tc->exp_err));
> +               return;
> +       }
> +
> +       if (tc->bytes_copied != TST_RET) {
> +               tst_res(TFAIL,
> +                       "Wrong number of bytes copied. Expected %d, copied
> %ld",
> +                       tc->bytes_copied, TST_RET);
> +               return;
> +       }
> +
> +       tst_res(TPASS, "copy_file_range ended with %s as expected",
> +                       tst_strerrno(tc->exp_err));
> +}
> +
> +static void cleanup(void)
> +{
> +       if (fd_dest > 0)
> +               SAFE_CLOSE(fd_dest);
> +       if (fd_src > 0)
> +               SAFE_CLOSE(fd_src);
> +       if (fd_rdonly > 0)
> +               SAFE_CLOSE(fd_rdonly);
> +       if (fd_mnted > 0)
> +               SAFE_CLOSE(fd_mnted);
> +       if (fd_dir > 0)
> +               SAFE_CLOSE(fd_dir);
> +}
> +
> +static void setup(void)
> +{
> +       syscall_info();
> +
> +       if (access(FILE_DIR_PATH, F_OK) == -1)
> +               SAFE_MKDIR(FILE_DIR_PATH, 0777);
> +
> +       fd_dir = SAFE_OPEN(FILE_DIR_PATH, O_RDONLY | O_DIRECTORY);
> +       fd_mnted = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> +       fd_src  = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_dest = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
> +
> +       SAFE_WRITE(1, fd_src,  CONTENT,  strlen(CONTENT));
> +}
> +
> +static struct tst_test test = {
> +       .test = verify_copy_file_range,
> +       .tcnt = ARRAY_SIZE(tcases),
> +       .setup = setup,
> +       .cleanup = cleanup,
> +       .min_kver = "4.5",
>

remove kver limitation as well.

> +       .needs_root = 1,
> +       .mount_device = 1,
> +       .mntpoint = MNTPOINT,
> +       .dev_fs_type = "ext4",
> +       .test_variants = TEST_VARIANTS,
> +};
>

Also saw some compiling(gcc version 4.8.5) warings:

copy_file_range02.c:44:2: warning: initializer element is not a constant
expression [enabled by default]
  {0,  0, strlen(CONTENT),  &fd_dest,   strlen(CONTENT),    false},
  ^
copy_file_range02.c:44:2: warning: (near initialization for
‘tcases[0].length’) [enabled by default]
copy_file_range02.c:44:2: warning: initializer element is not a constant
expression [enabled by default]
copy_file_range02.c:44:2: warning: (near initialization for
‘tcases[0].bytes_copied’) [enabled by default]
copy_file_range02.c:45:2: warning: initializer element is not a constant
expression [enabled by default]
  {0, 10, strlen(CONTENT),  &fd_dest,   strlen(CONTENT),    false},


Beside that, I get a new failure in the test, I will look into that to see
if it's kernel bug or testcase issue then.

copy_file_range.h:32: INFO: Testing tst copy_file_range()
copy_file_range02.c:76: PASS: copy_file_range ended with SUCCESS as expected
copy_file_range02.c:76: PASS: copy_file_range ended with SUCCESS as expected
copy_file_range02.c:76: PASS: copy_file_range ended with SUCCESS as expected
copy_file_range02.c:76: PASS: copy_file_range ended with EBADF as expected
copy_file_range02.c:76: PASS: copy_file_range ended with EXDEV as expected
copy_file_range02.c:64: FAIL: copy_file_range failed with EBADF, expected
EISDIR

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range03.c
> b/testcases/kernel/syscalls/copy_file_range/copy_file_range03.c
> new file mode 100644
> index 000000000..68a4b2ac3
> --- /dev/null
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range03.c
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 SUSE LLC
> + * Author: Christian Amann <camann@suse.com>
> + */
> +
> +/*
> + * Copies the contents of one file into another and
> + * checks if the timestamp gets updated in the process.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include "tst_test.h"
> +#include "copy_file_range.h"
> +
> +static int fd_src;
> +static int fd_dest;
> +
> +unsigned long getTimestamp(int fd)
> +{
> +       struct stat filestat;
> +
> +       fstat(fd, &filestat);
> +       return filestat.st_mtime;
> +}
> +
> +static void verify_copy_file_range_timestamp(void)
> +{
> +       loff_t offset;
> +       unsigned long timestamp, updated_timestamp;
> +
> +       timestamp = getTimestamp(fd_dest);
> +       usleep(1000000);
> +
> +       offset = 0;
> +       TEST(sys_copy_file_range(fd_src, &offset,
> +                       fd_dest, 0, strlen(CONTENT), 0));
> +       if (TST_RET == -1) {
> +               tst_res(TFAIL, "copy_file_range unexpectedly failed!");
> +               return;
> +       }
> +
> +       updated_timestamp = getTimestamp(fd_dest);
> +
> +       if (timestamp == updated_timestamp) {
> +               tst_res(TFAIL, "copy_file_range did not update
> timestamp!");
> +               return;
> +       }
> +
> +       tst_res(TPASS, "copy_file_range sucessfully updated the
> timestamp.");
> +}
> +
> +static void cleanup(void)
> +{
> +       if (fd_dest > 0)
> +               SAFE_CLOSE(fd_dest);
> +       if (fd_src  > 0)
> +               SAFE_CLOSE(fd_src);
> +}
> +
> +static void setup(void)
> +{
> +       syscall_info();
> +
> +       fd_dest = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_src  = SAFE_OPEN(FILE_SRC_PATH,  O_RDWR | O_CREAT, 0664);
> +       SAFE_WRITE(1, fd_src,  CONTENT,  strlen(CONTENT));
> +       SAFE_CLOSE(fd_src);
> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY);
> +}
> +
> +
> +static struct tst_test test = {
> +       .test_all = verify_copy_file_range_timestamp,
> +       .setup = setup,
> +       .cleanup = cleanup,
> +       .min_kver = "4.5",
>

here as well.

> +       .needs_tmpdir = 1,
> +       .test_variants = TEST_VARIANTS,
> +};
> --
> 2.16.4
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>


-- 
Regards,
Li Wang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190424/1d117d76/attachment-0001.html>


More information about the ltp mailing list