All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-07-03  3:41 Yang Xu
  2019-07-05 15:22 ` Amir Goldstein
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-03  3:41 UTC (permalink / raw)
  To: ltp

Since Amir path for copy_file_range has been merged into linux-xfs,
I add test for swapfile, immutable file, bounds in ltp.  Also, add test
for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
constraint[2]).  I follow xfstests code[3][4][5] and increase it .

[1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
[2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
[3]https://patchwork.kernel.org/patch/10971759/
[4]https://patchwork.kernel.org/patch/10971747/
[5]https://patchwork.kernel.org/patch/10961421/

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../copy_file_range/copy_file_range.h         |  11 +-
 .../copy_file_range/copy_file_range02.c       | 127 +++++++++++++++---
 2 files changed, 118 insertions(+), 20 deletions(-)

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..22bbb46a5 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,6 +9,7 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
 #include "lapi/syscalls.h"
 
 #define TEST_VARIANTS	2
@@ -18,10 +19,18 @@
 #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 FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_BLKDEV    "file_blk"
+#define FILE_CHRDEV    "file_chr"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_OFF   9223372036854712050
+#define MIN_OFF   65537
+#define MAX_LEN   9223372036854775807
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..b408d738d 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     8EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond 8TiB ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,61 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static void run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	break;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	break;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,33 +117,81 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+
+	SAFE_UNLINK(FILE_BLKDEV);
+	SAFE_UNLINK(FILE_CHRDEV);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
 {
 	syscall_info();
+	int swap_flag = 1;
+	dev_t dev[3];
+
+	dev[1] = makedev(7, 3);
+	dev[2] = makedev(7, 4);
+	dev[3] = makedev(7, 5);
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 
+	SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, dev[1]);
+	SAFE_MKNOD(FILE_CHRDEV, S_IFCHR | 0777, dev[2]);
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, dev[3]);
+
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+	fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0664);
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0664);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0664);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_flag = 0;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_flag = 0;
+	}
+	if (swap_flag) {
+		run_command("mkswap", FILE_SWAP_PATH, NULL);
+		run_command("swapon", FILE_SWAP_PATH, NULL);
+	}
 }
 
 static struct tst_test test = {
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-03  3:41 [LTP] [PATCH] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-05 15:22 ` Amir Goldstein
  2019-07-05 20:42   ` [LTP] [PATCH v2] " Yang Xu
  2019-07-08 10:38   ` [LTP] [PATCH] " Yang Xu
  0 siblings, 2 replies; 86+ messages in thread
From: Amir Goldstein @ 2019-07-05 15:22 UTC (permalink / raw)
  To: ltp

On Fri, Jul 5, 2019 at 12:37 PM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Since Amir path for copy_file_range has been merged into linux-xfs,
> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
>
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
> [3]https://patchwork.kernel.org/patch/10971759/
> [4]https://patchwork.kernel.org/patch/10971747/
> [5]https://patchwork.kernel.org/patch/10961421/
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  .../copy_file_range/copy_file_range.h         |  11 +-
>  .../copy_file_range/copy_file_range02.c       | 127 +++++++++++++++---
>  2 files changed, 118 insertions(+), 20 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> index b6d132978..22bbb46a5 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -9,6 +9,7 @@
>
>  #include <stdbool.h>
>  #include <unistd.h>
> +#include <sys/sysmacros.h>
>  #include "lapi/syscalls.h"
>
>  #define TEST_VARIANTS  2
> @@ -18,10 +19,18 @@
>  #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 FILE_IMMUTABLE_PATH "file_immutable"
> +#define FILE_SWAP_PATH "file_swap"
> +#define FILE_BLKDEV    "file_blk"
> +#define FILE_CHRDEV    "file_chr"
> +#define FILE_FIFO      "file_fifo"
> +#define FILE_COPY_PATH  "file_copy"
>
>  #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>  #define CONTSIZE       (sizeof(CONTENT) - 1)
> +#define MAX_OFF   9223372036854712050

Please use the expression instead of the unexplained value

> +#define MIN_OFF   65537
> +#define MAX_LEN   9223372036854775807

Same here

>
>  static void syscall_info(void)
>  {
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 07c0207c2..b408d738d 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -10,15 +10,25 @@
>   *
>   * 1) Try to copy contents to file open as readonly
>   *    -> EBADF
> - * 2) Try to copy contents to file on different mounted
> - *    filesystem -> EXDEV
> - * 3) Try to copy contents to directory -> EISDIR
> - * 4) Try to copy contents to a file opened with the
> + * 2) Try to copy contents to directory -> EISDIR
> + * 3) Try to copy contents to a file opened with the
>   *    O_APPEND flag -> EBADF
> - * 5) Try to copy contents to closed filedescriptor
> + * 4) Try to copy contents to closed filedescriptor
>   *    -> EBADF
> - * 6) Try to copy contents with invalid 'flags' value
> + * 5) Try to copy contents with invalid 'flags' value
>   *    -> EINVAL
> + * 6) Try to copy contents to a file chattred with +i
> + *    flag -> EPERM
> + * 7) Try to copy contents to a swapfile ->ETXTBSY
> + * 8) Try to copy contents to the samefile with overlapping
> + *    ->EINVAL
> + * 9) Try to copy contents to a blkdev ->EINVAL
> + * 10) Try to copy contents to a chardev ->EINVAL
> + * 11) Try to copy contents to a FIFO ->EINVAL
> + * 12) Try to copy contents to a file with length beyond
> + *     8EiB wraps around 0 -> EOVERFLOW
> + * 13) Try to copy contents to a file with target file range
> + *     beyond 8TiB ->EFBIG
>   */
>
>  #define _GNU_SOURCE
> @@ -29,30 +39,61 @@
>  static int fd_src;
>  static int fd_dest;
>  static int fd_rdonly;
> -static int fd_mnted;
>  static int fd_dir;
>  static int fd_closed;
>  static int fd_append;
> +static int fd_immutable;
> +static int fd_swapfile;
> +static int fd_dup;
> +static int fd_blkdev;
> +static int fd_chrdev;
> +static int fd_fifo;
> +static int fd_copy;
>
>  static struct tcase {
>         int     *copy_to_fd;
>         int     flags;
>         int     exp_err;
> +       loff_t  dst;
> +       loff_t     len;
>  } tcases[] = {
> -       {&fd_rdonly,    0,      EBADF},
> -       {&fd_mnted,     0,      EXDEV},
> -       {&fd_dir,       0,      EISDIR},
> -       {&fd_append,    0,      EBADF},
> -       {&fd_closed,    0,      EBADF},
> -       {&fd_dest,      -1,     EINVAL},
> +       {&fd_rdonly,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dir,       0,   EISDIR,     0,     CONTSIZE},
> +       {&fd_append,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_closed,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dest,      -1,  EINVAL,     0,     CONTSIZE},
> +       {&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
> +       {&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
> +       {&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
> +       {&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
> +       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
>
> +static void run_command(char *command, char *option, char *file)
> +{
> +       const char *const cmd[] = {command, option, file, NULL};
> +       int ret;
> +
> +       ret = tst_run_cmd(cmd, NULL, NULL, 1);
> +       switch (ret) {
> +       case 0:
> +       break;
> +       case 255:
> +               tst_res(TCONF, "%s binary not installed", command);
> +       break;
> +       default:
> +               tst_res(TCONF, "%s exited with %i", command, ret);
> +       }
> +}
> +
>  static void verify_copy_file_range(unsigned int n)
>  {
>         struct tcase *tc = &tcases[n];
> -
>         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
> -                               0, CONTSIZE, tc->flags));
> +                               &tc->dst, tc->len, tc->flags));
>
>         if (TST_RET == -1) {
>                 if (tc->exp_err == TST_ERR) {
> @@ -76,33 +117,81 @@ static void cleanup(void)
>                 SAFE_CLOSE(fd_append);
>         if (fd_dir > 0)
>                 SAFE_CLOSE(fd_dir);
> -       if (fd_mnted > 0)
> -               SAFE_CLOSE(fd_mnted);
>         if (fd_rdonly > 0)
>                 SAFE_CLOSE(fd_rdonly);
>         if (fd_dest > 0)
>                 SAFE_CLOSE(fd_dest);
>         if (fd_src > 0)
>                 SAFE_CLOSE(fd_src);
> +       if (fd_immutable > 0) {
> +               run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
> +               SAFE_CLOSE(fd_immutable);
> +       }
> +       if (fd_swapfile > 0) {
> +               run_command("swapoff", FILE_SWAP_PATH, NULL);
> +               SAFE_CLOSE(fd_swapfile);
> +       }
> +       if (fd_dup > 0)
> +               SAFE_CLOSE(fd_dup);
> +       if (fd_copy > 0)
> +               SAFE_CLOSE(fd_copy);
> +
> +       SAFE_UNLINK(FILE_BLKDEV);
> +       SAFE_UNLINK(FILE_CHRDEV);
> +       SAFE_UNLINK(FILE_FIFO);
>  }
>
>  static void setup(void)
>  {
>         syscall_info();
> +       int swap_flag = 1;
> +       dev_t dev[3];
> +
> +       dev[1] = makedev(7, 3);

You've picked /dev/loop3, which is high likely to be a real device
on a system where this test is run and with release kernel this test
may write over that real device - not a good thing.
My xfstest uses device (7, 123), which has better odds to be unused,
but I think I may switch to a test owned device before proposing the
test for merge.

> +       dev[2] = makedev(7, 4);

Would be safer to use a known device like /dev/null IMO

> +       dev[3] = makedev(7, 5);

dev[3] not needed for S_FIFO

>
>         if (access(FILE_DIR_PATH, F_OK) == -1)
>                 SAFE_MKDIR(FILE_DIR_PATH, 0777);
>
> +       SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, dev[1]);
> +       SAFE_MKNOD(FILE_CHRDEV, S_IFCHR | 0777, dev[2]);

Would be safer to use a known device like /dev/null IMO

> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, dev[3]);
> +
>         fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>         fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>         fd_closed = -1;
>         fd_append = SAFE_OPEN(FILE_DEST_PATH,
>                         O_RDWR | O_CREAT | O_APPEND, 0664);
> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
> +       fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0664);
> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0664);
> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0664);
> +
> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
> +       close(fd_src);
> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
> +
> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
> +       run_command("chattr", "+i", FILE_IMMUTABLE_PATH);

fs may not support chattr +i. immutable file test case should be
skipped in that case.

>
> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
> +               tst_res(TCONF, "Insufficient disk space to create swap file");
> +               swap_flag = 0;
> +       }
> +
> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
> +               tst_res(TCONF, "Failed to create swapfile");
> +               swap_flag = 0;
> +       }
> +       if (swap_flag) {
> +               run_command("mkswap", FILE_SWAP_PATH, NULL);
> +               run_command("swapon", FILE_SWAP_PATH, NULL);

fs may not support swap. swapfile test case should be skipped in that case.

Please make sure run your test on release kernel and not only on xfs-next
when you test it.
You may want to run on older kernel with btrfs to see how no support
for swapfiles behaves.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-05 15:22 ` Amir Goldstein
@ 2019-07-05 20:42   ` Yang Xu
  2019-07-08 15:17     ` Amir Goldstein
  2019-07-08 10:38   ` [LTP] [PATCH] " Yang Xu
  1 sibling, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-05 20:42 UTC (permalink / raw)
  To: ltp

Since Amir path for copy_file_range has been merged into linux-xfs,
I add test for swapfile, immutable file, bounds in ltp.  Also, add test
for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
constraint[2]).  I follow xfstests code[3][4][5] and increase it .

[1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
[2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
[3]https://patchwork.kernel.org/patch/10971759/
[4]https://patchwork.kernel.org/patch/10971747/
[5]https://patchwork.kernel.org/patch/10961421/

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../copy_file_range/copy_file_range.h         |  11 +-
 .../copy_file_range/copy_file_range02.c       | 139 +++++++++++++++---
 2 files changed, 130 insertions(+), 20 deletions(-)

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..f9e2565d9 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,6 +9,7 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
 #include "lapi/syscalls.h"
 
 #define TEST_VARIANTS	2
@@ -18,10 +19,18 @@
 #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 FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_BLKDEV    "file_blk"
+#define FILE_CHRDEV    "file_chr"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_LEN   ((long long)(~0ULL >> 1))
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..89519ac1d 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     8EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond 8TiB ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,74 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
+	if (tc->exp_err == ETXTBSY && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->exp_err == EPERM && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
 
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,33 +130,80 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+
+	SAFE_UNLINK(FILE_BLKDEV);
+	SAFE_UNLINK(FILE_CHRDEV);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
 {
 	syscall_info();
+	dev_t dev[2];
+
+	dev[1] = makedev(7, 127);
+	dev[2] = makedev(1, 3);
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 
+	SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, dev[1]);
+	SAFE_MKNOD(FILE_CHRDEV, S_IFCHR | 0777, dev[2]);
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
+
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+	fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0664);
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0664);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0664);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +214,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-05 15:22 ` Amir Goldstein
  2019-07-05 20:42   ` [LTP] [PATCH v2] " Yang Xu
@ 2019-07-08 10:38   ` Yang Xu
  1 sibling, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-08 10:38 UTC (permalink / raw)
  To: ltp

on  2019/07/05 23:22, Amir Goldstein wrote:

> On Fri, Jul 5, 2019 at 12:37 PM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> Since Amir path for copy_file_range has been merged into linux-xfs,
>> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
>> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
>> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
>>
>> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
>> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
>> [3]https://patchwork.kernel.org/patch/10971759/
>> [4]https://patchwork.kernel.org/patch/10971747/
>> [5]https://patchwork.kernel.org/patch/10961421/
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> ---
>>   .../copy_file_range/copy_file_range.h         |  11 +-
>>   .../copy_file_range/copy_file_range02.c       | 127 +++++++++++++++---
>>   2 files changed, 118 insertions(+), 20 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> index b6d132978..22bbb46a5 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> @@ -9,6 +9,7 @@
>>
>>   #include<stdbool.h>
>>   #include<unistd.h>
>> +#include<sys/sysmacros.h>
>>   #include "lapi/syscalls.h"
>>
>>   #define TEST_VARIANTS  2
>> @@ -18,10 +19,18 @@
>>   #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 FILE_IMMUTABLE_PATH "file_immutable"
>> +#define FILE_SWAP_PATH "file_swap"
>> +#define FILE_BLKDEV    "file_blk"
>> +#define FILE_CHRDEV    "file_chr"
>> +#define FILE_FIFO      "file_fifo"
>> +#define FILE_COPY_PATH  "file_copy"
>>
>>   #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>>   #define CONTSIZE       (sizeof(CONTENT) - 1)
>> +#define MAX_OFF   9223372036854712050
> Please use the expression instead of the unexplained value
OK.  I will use the following code instead of it.

#define MAX_LEN   ((long long)(~0ULL>>  1))
#define MIN_OFF   65537
#define MAX_OFF   (MAX_LEN - MIN_OFF)


>> +#define MIN_OFF   65537
>> +#define MAX_LEN   9223372036854775807
> Same here
>
>>   static void syscall_info(void)
>>   {
>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> index 07c0207c2..b408d738d 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> @@ -10,15 +10,25 @@
>>    *
>>    * 1) Try to copy contents to file open as readonly
>>    *    ->  EBADF
>> - * 2) Try to copy contents to file on different mounted
>> - *    filesystem ->  EXDEV
>> - * 3) Try to copy contents to directory ->  EISDIR
>> - * 4) Try to copy contents to a file opened with the
>> + * 2) Try to copy contents to directory ->  EISDIR
>> + * 3) Try to copy contents to a file opened with the
>>    *    O_APPEND flag ->  EBADF
>> - * 5) Try to copy contents to closed filedescriptor
>> + * 4) Try to copy contents to closed filedescriptor
>>    *    ->  EBADF
>> - * 6) Try to copy contents with invalid 'flags' value
>> + * 5) Try to copy contents with invalid 'flags' value
>>    *    ->  EINVAL
>> + * 6) Try to copy contents to a file chattred with +i
>> + *    flag ->  EPERM
>> + * 7) Try to copy contents to a swapfile ->ETXTBSY
>> + * 8) Try to copy contents to the samefile with overlapping
>> + *    ->EINVAL
>> + * 9) Try to copy contents to a blkdev ->EINVAL
>> + * 10) Try to copy contents to a chardev ->EINVAL
>> + * 11) Try to copy contents to a FIFO ->EINVAL
>> + * 12) Try to copy contents to a file with length beyond
>> + *     8EiB wraps around 0 ->  EOVERFLOW
>> + * 13) Try to copy contents to a file with target file range
>> + *     beyond 8TiB ->EFBIG
>>    */
>>
>>   #define _GNU_SOURCE
>> @@ -29,30 +39,61 @@
>>   static int fd_src;
>>   static int fd_dest;
>>   static int fd_rdonly;
>> -static int fd_mnted;
>>   static int fd_dir;
>>   static int fd_closed;
>>   static int fd_append;
>> +static int fd_immutable;
>> +static int fd_swapfile;
>> +static int fd_dup;
>> +static int fd_blkdev;
>> +static int fd_chrdev;
>> +static int fd_fifo;
>> +static int fd_copy;
>>
>>   static struct tcase {
>>          int     *copy_to_fd;
>>          int     flags;
>>          int     exp_err;
>> +       loff_t  dst;
>> +       loff_t     len;
>>   } tcases[] = {
>> -       {&fd_rdonly,    0,      EBADF},
>> -       {&fd_mnted,     0,      EXDEV},
>> -       {&fd_dir,       0,      EISDIR},
>> -       {&fd_append,    0,      EBADF},
>> -       {&fd_closed,    0,      EBADF},
>> -       {&fd_dest,      -1,     EINVAL},
>> +       {&fd_rdonly,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_dir,       0,   EISDIR,     0,     CONTSIZE},
>> +       {&fd_append,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_closed,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_dest,      -1,  EINVAL,     0,     CONTSIZE},
>> +       {&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
>> +       {&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
>> +       {&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
>> +       {&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
>> +       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>>   };
>>
>> +static void run_command(char *command, char *option, char *file)
>> +{
>> +       const char *const cmd[] = {command, option, file, NULL};
>> +       int ret;
>> +
>> +       ret = tst_run_cmd(cmd, NULL, NULL, 1);
>> +       switch (ret) {
>> +       case 0:
>> +       break;
>> +       case 255:
>> +               tst_res(TCONF, "%s binary not installed", command);
>> +       break;
>> +       default:
>> +               tst_res(TCONF, "%s exited with %i", command, ret);
>> +       }
>> +}
>> +
>>   static void verify_copy_file_range(unsigned int n)
>>   {
>>          struct tcase *tc =&tcases[n];
>> -
>>          TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
>> -                               0, CONTSIZE, tc->flags));
>> +&tc->dst, tc->len, tc->flags));
>>
>>          if (TST_RET == -1) {
>>                  if (tc->exp_err == TST_ERR) {
>> @@ -76,33 +117,81 @@ static void cleanup(void)
>>                  SAFE_CLOSE(fd_append);
>>          if (fd_dir>  0)
>>                  SAFE_CLOSE(fd_dir);
>> -       if (fd_mnted>  0)
>> -               SAFE_CLOSE(fd_mnted);
>>          if (fd_rdonly>  0)
>>                  SAFE_CLOSE(fd_rdonly);
>>          if (fd_dest>  0)
>>                  SAFE_CLOSE(fd_dest);
>>          if (fd_src>  0)
>>                  SAFE_CLOSE(fd_src);
>> +       if (fd_immutable>  0) {
>> +               run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
>> +               SAFE_CLOSE(fd_immutable);
>> +       }
>> +       if (fd_swapfile>  0) {
>> +               run_command("swapoff", FILE_SWAP_PATH, NULL);
>> +               SAFE_CLOSE(fd_swapfile);
>> +       }
>> +       if (fd_dup>  0)
>> +               SAFE_CLOSE(fd_dup);
>> +       if (fd_copy>  0)
>> +               SAFE_CLOSE(fd_copy);
>> +
>> +       SAFE_UNLINK(FILE_BLKDEV);
>> +       SAFE_UNLINK(FILE_CHRDEV);
>> +       SAFE_UNLINK(FILE_FIFO);
>>   }
>>
>>   static void setup(void)
>>   {
>>          syscall_info();
>> +       int swap_flag = 1;
>> +       dev_t dev[3];
>> +
>> +       dev[1] = makedev(7, 3);
> You've picked /dev/loop3, which is high likely to be a real device
> on a system where this test is run and with release kernel this test
> may write over that real device - not a good thing.
> My xfstest uses device (7, 123), which has better odds to be unused,
> but I think I may switch to a test owned device before proposing the
> test for merge.
>
I see.
>> +       dev[2] = makedev(7, 4);
> Would be safer to use a known device like /dev/null IMO
OK. I got it.
>> +       dev[3] = makedev(7, 5);
> dev[3] not needed for S_FIFO
>
I see.
>>          if (access(FILE_DIR_PATH, F_OK) == -1)
>>                  SAFE_MKDIR(FILE_DIR_PATH, 0777);
>>
>> +       SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, dev[1]);
>> +       SAFE_MKNOD(FILE_CHRDEV, S_IFCHR | 0777, dev[2]);
> Would be safer to use a known device like /dev/null IMO
>
>> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, dev[3]);
>> +
>>          fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
>> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>>          fd_closed = -1;
>>          fd_append = SAFE_OPEN(FILE_DEST_PATH,
>>                          O_RDWR | O_CREAT | O_APPEND, 0664);
>> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
>> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
>> +       fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0664);
>> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0664);
>> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0664);
>> +
>> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
>> +       close(fd_src);
>> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
>> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
>> +
>> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
>> +       run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> fs may not support chattr +i. immutable file test case should be
> skipped in that case.
>
>> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
>> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
>> +               tst_res(TCONF, "Insufficient disk space to create swap file");
>> +               swap_flag = 0;
>> +       }
>> +
>> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
>> +               tst_res(TCONF, "Failed to create swapfile");
>> +               swap_flag = 0;
>> +       }
>> +       if (swap_flag) {
>> +               run_command("mkswap", FILE_SWAP_PATH, NULL);
>> +               run_command("swapon", FILE_SWAP_PATH, NULL);
> fs may not support swap. swapfile test case should be skipped in that case.
>
> Please make sure run your test on release kernel and not only on xfs-next
> when you test it.
> You may want to run on older kernel with btrfs to see how no support
> for swapfiles behaves.
>
Now I test it on  upstream kernel  5.2.  Currently, we test this case on 
ext4 filesystem,  I think we can test on all filesystems and
skip swapfile or immutable file if filesystem doesn't support it.

Thanks
Yang Xu

> Thanks,
> Amir.
>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-05 20:42   ` [LTP] [PATCH v2] " Yang Xu
@ 2019-07-08 15:17     ` Amir Goldstein
  2019-07-09  6:57       ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-08 15:17 UTC (permalink / raw)
  To: ltp

On Mon, Jul 8, 2019 at 1:46 PM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Since Amir path for copy_file_range has been merged into linux-xfs,
> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
>
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
> [3]https://patchwork.kernel.org/patch/10971759/
> [4]https://patchwork.kernel.org/patch/10971747/
> [5]https://patchwork.kernel.org/patch/10961421/
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  .../copy_file_range/copy_file_range.h         |  11 +-
>  .../copy_file_range/copy_file_range02.c       | 139 +++++++++++++++---
>  2 files changed, 130 insertions(+), 20 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> index b6d132978..f9e2565d9 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -9,6 +9,7 @@
>
>  #include <stdbool.h>
>  #include <unistd.h>
> +#include <sys/sysmacros.h>
>  #include "lapi/syscalls.h"
>
>  #define TEST_VARIANTS  2
> @@ -18,10 +19,18 @@
>  #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 FILE_IMMUTABLE_PATH "file_immutable"
> +#define FILE_SWAP_PATH "file_swap"
> +#define FILE_BLKDEV    "file_blk"
> +#define FILE_CHRDEV    "file_chr"
> +#define FILE_FIFO      "file_fifo"
> +#define FILE_COPY_PATH  "file_copy"
>
>  #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>  #define CONTSIZE       (sizeof(CONTENT) - 1)
> +#define MAX_LEN   ((long long)(~0ULL >> 1))
> +#define MIN_OFF   65537
> +#define MAX_OFF   (MAX_LEN - MIN_OFF)

In the xfstest the value of MAX_OFF is ((1ULL << 63) - MIN_OFF)
Not sure why it was changed here?

>
[...]
> +
>  static void verify_copy_file_range(unsigned int n)
>  {
>         struct tcase *tc = &tcases[n];
> +       if (tc->exp_err == ETXTBSY && chattr_i_nsup) {

if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup)

Would have made much more sense to code readers.

> +               tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
> +               return;
> +       }
> +       if (tc->exp_err == EPERM && swap_nsup) {

Same here.

> +               tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
> +               return;
> +       }
>
>         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
> -                               0, CONTSIZE, tc->flags));
> +                               &tc->dst, tc->len, tc->flags));
>
[...]

>
>  static void setup(void)
>  {
>         syscall_info();
> +       dev_t dev[2];
> +
> +       dev[1] = makedev(7, 127);

As I wrote before, while it is probable the loop127 is free it is not safe
programming to assume it is free, especially not if you are trying to overwrite
its content!
I suggest that you alter  find_free_loopdev() to return the free loopdev minor
(and -1 for no free loopdev) and then you can safely use the minor number
that find_free_loopdev() returned in this test.
If there is no free loopdev you can return TCONF.

> +       dev[2] = makedev(1, 3);

What I meant was
#define FILE_CHRDEV "/dev/null"

Obviously, no need to mknod nor unlink it on cleanup...

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-08 15:17     ` Amir Goldstein
@ 2019-07-09  6:57       ` Yang Xu
  2019-07-09 10:06         ` Amir Goldstein
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-09  6:57 UTC (permalink / raw)
  To: ltp

on 2019/07/08 23:17, Amir Goldstein wrote:

> On Mon, Jul 8, 2019 at 1:46 PM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> Since Amir path for copy_file_range has been merged into linux-xfs,
>> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
>> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
>> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
>>
>> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
>> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
>> [3]https://patchwork.kernel.org/patch/10971759/
>> [4]https://patchwork.kernel.org/patch/10971747/
>> [5]https://patchwork.kernel.org/patch/10961421/
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> ---
>>   .../copy_file_range/copy_file_range.h         |  11 +-
>>   .../copy_file_range/copy_file_range02.c       | 139 +++++++++++++++---
>>   2 files changed, 130 insertions(+), 20 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> index b6d132978..f9e2565d9 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> @@ -9,6 +9,7 @@
>>
>>   #include<stdbool.h>
>>   #include<unistd.h>
>> +#include<sys/sysmacros.h>
>>   #include "lapi/syscalls.h"
>>
>>   #define TEST_VARIANTS  2
>> @@ -18,10 +19,18 @@
>>   #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 FILE_IMMUTABLE_PATH "file_immutable"
>> +#define FILE_SWAP_PATH "file_swap"
>> +#define FILE_BLKDEV    "file_blk"
>> +#define FILE_CHRDEV    "file_chr"
>> +#define FILE_FIFO      "file_fifo"
>> +#define FILE_COPY_PATH  "file_copy"
>>
>>   #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>>   #define CONTSIZE       (sizeof(CONTENT) - 1)
>> +#define MAX_LEN   ((long long)(~0ULL>>  1))
>> +#define MIN_OFF   65537
>> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
> In the xfstest the value of MAX_OFF is ((1ULL<<  63) - MIN_OFF)
> Not sure why it was changed here?
Because the LONG LONG max value in kernel linux/limit.h is defined as" #define LLONG_MAX  ((long long)(~0ULL>>  1))".
I think it is a common usage.   If you don't like this way, I will use the xfstests vaule.


> [...]
>> +
>>   static void verify_copy_file_range(unsigned int n)
>>   {
>>          struct tcase *tc =&tcases[n];
>> +       if (tc->exp_err == ETXTBSY&&  chattr_i_nsup) {
> if (tc->copy_to_fd ==&fd_immutable&&  chattr_i_nsup)
>
> Would have made much more sense to code readers.
Yes.

>> +               tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
>> +               return;
>> +       }
>> +       if (tc->exp_err == EPERM&&  swap_nsup) {
> Same here.
OK.

>> +               tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
>> +               return;
>> +       }
>>
>>          TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
>> -                               0, CONTSIZE, tc->flags));
>> +&tc->dst, tc->len, tc->flags));
>>
> [...]
>
>>   static void setup(void)
>>   {
>>          syscall_info();
>> +       dev_t dev[2];
>> +
>> +       dev[1] = makedev(7, 127);
> As I wrote before, while it is probable the loop127 is free it is not safe
> programming to assume it is free, especially not if you are trying to overwrite
> its content!
> I suggest that you alter  find_free_loopdev() to return the free loopdev minor
> (and -1 for no free loopdev) and then you can safely use the minor number
> that find_free_loopdev() returned in this test.
> If there is no free loopdev you can return TCONF.
Hi Amir

Thank for you mentionation.  Befor this, I don't know the find_free_loopdev api in ltp. 
If I alter it, I think we can add find_free_loopdev document in doc/test-writing-guidelines.txt.

I will send  a v3 patch for your comment.

>> +       dev[2] = makedev(1, 3);
> What I meant was
> #define FILE_CHRDEV "/dev/null"
>
> Obviously, no need to mknod nor unlink it on cleanup...
OK. This way is great.

> Thanks,
> Amir.
>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-09  6:57       ` Yang Xu
@ 2019-07-09 10:06         ` Amir Goldstein
  2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
  2019-07-10  7:32           ` [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  0 siblings, 2 replies; 86+ messages in thread
From: Amir Goldstein @ 2019-07-09 10:06 UTC (permalink / raw)
  To: ltp

On Tue, Jul 9, 2019 at 9:57 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> on 2019/07/08 23:17, Amir Goldstein wrote:
>
> > On Mon, Jul 8, 2019 at 1:46 PM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
> >> Since Amir path for copy_file_range has been merged into linux-xfs,
> >> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
> >> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
> >> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
> >>
> >> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
> >> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
> >> [3]https://patchwork.kernel.org/patch/10971759/
> >> [4]https://patchwork.kernel.org/patch/10971747/
> >> [5]https://patchwork.kernel.org/patch/10961421/
> >>
> >> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
> >> ---
> >>   .../copy_file_range/copy_file_range.h         |  11 +-
> >>   .../copy_file_range/copy_file_range02.c       | 139 +++++++++++++++---
> >>   2 files changed, 130 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> >> index b6d132978..f9e2565d9 100644
> >> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> >> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> >> @@ -9,6 +9,7 @@
> >>
> >>   #include<stdbool.h>
> >>   #include<unistd.h>
> >> +#include<sys/sysmacros.h>
> >>   #include "lapi/syscalls.h"
> >>
> >>   #define TEST_VARIANTS  2
> >> @@ -18,10 +19,18 @@
> >>   #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 FILE_IMMUTABLE_PATH "file_immutable"
> >> +#define FILE_SWAP_PATH "file_swap"
> >> +#define FILE_BLKDEV    "file_blk"
> >> +#define FILE_CHRDEV    "file_chr"
> >> +#define FILE_FIFO      "file_fifo"
> >> +#define FILE_COPY_PATH  "file_copy"
> >>
> >>   #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
> >>   #define CONTSIZE       (sizeof(CONTENT) - 1)
> >> +#define MAX_LEN   ((long long)(~0ULL>>  1))
> >> +#define MIN_OFF   65537
> >> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
> > In the xfstest the value of MAX_OFF is ((1ULL<<  63) - MIN_OFF)
> > Not sure why it was changed here?
> Because the LONG LONG max value in kernel linux/limit.h is defined as" #define LLONG_MAX  ((long long)(~0ULL>>  1))".
> I think it is a common usage.   If you don't like this way, I will use the xfstests vaule.

No it makes sense. VFS max size is larger than XFS max size and
I think btrfs is limited for the VFS max.

Maybe it is better to define MAX_LFS_FILESIZE if it is not defined
in some ltp header file and #define MAX_LEN MAX_LFS_FILESIZE
leaving comments where due.

Also, I now wonder if running this test on 32bit kernel and with test
compiled for 32bit will yield the expected errors?

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev()
  2019-07-09 10:06         ` Amir Goldstein
@ 2019-07-10  7:18           ` Yang Xu
  2019-07-10  7:18             ` [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
                               ` (2 more replies)
  2019-07-10  7:32           ` [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  1 sibling, 3 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-10  7:18 UTC (permalink / raw)
  To: ltp

Alter find_free_loopdev() to return the free loopdev minor
(and -1 for no free loopdev) and then WE can safely use the
minor number that find_free_loopdev() returned in test cases.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 doc/test-writing-guidelines.txt |  9 +++++++++
 include/tst_device.h            |  6 ++++++
 lib/tst_device.c                | 12 ++++++------
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index c6d4e001d..887801e68 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1045,6 +1045,15 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
 -------------------------------------------------------------------------------
 #include "tst_test.h"
 
+int find_free_loopdev();
+-------------------------------------------------------------------------------
+This function finds a free loopdev for use and returns the free loopdev minor(-1
+for no free loopdev).
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
 unsigned long tst_dev_bytes_written(const char *dev);
 -------------------------------------------------------------------------------
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 61902b7e0..8953b0828 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -44,6 +44,12 @@ int tst_umount(const char *path);
  */
 int tst_clear_device(const char *dev);
 
+/*
+ * Finds a free loop device for use and returns the free loopdev minor(-1 for no
+ * free loopdev).
+ */
+int find_free_loopdev(void);
+
 /*
  * Reads test block device stat file and returns the bytes written since the
  * last call of this function.
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 65fcc1337..3b87dd1f1 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -68,7 +68,7 @@ static int set_dev_path(int dev)
 	return 0;
 }
 
-static int find_free_loopdev(void)
+int find_free_loopdev(void)
 {
 	int ctl_fd, dev_fd, rc, i;
 	struct loop_info loopinfo;
@@ -82,10 +82,10 @@ static int find_free_loopdev(void)
 		if (rc >= 0) {
 			set_dev_path(rc);
 			tst_resm(TINFO, "Found free device '%s'", dev_path);
-			return 0;
+			return rc;
 		}
 		tst_resm(TINFO, "Couldn't find free loop device");
-		return 1;
+		return -1;
 	}
 
 	switch (errno) {
@@ -121,7 +121,7 @@ static int find_free_loopdev(void)
 				continue;
 			tst_resm(TINFO, "Found free device '%s'", dev_path);
 			close(dev_fd);
-			return 0;
+			return i;
 		}
 
 		close(dev_fd);
@@ -129,7 +129,7 @@ static int find_free_loopdev(void)
 
 	tst_resm(TINFO, "No free devices found");
 
-	return 1;
+	return -1;
 }
 
 static int attach_device(const char *dev, const char *file)
@@ -274,7 +274,7 @@ const char *tst_acquire_device__(unsigned int size)
 		return NULL;
 	}
 
-	if (find_free_loopdev())
+	if (find_free_loopdev() == -1)
 		return NULL;
 
 	if (attach_device(dev_path, DEV_FILE))
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
@ 2019-07-10  7:18             ` Yang Xu
  2019-07-10  7:50               ` Amir Goldstein
  2019-07-10  7:18             ` [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-10  7:47             ` [LTP] [PATCH v3 " Amir Goldstein
  2 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-10  7:18 UTC (permalink / raw)
  To: ltp

Amir has relaxed cross-device constraint since commit(vfs: allow
copy_file_range to copy across devices), I think we can remove it
in copy_file_range02 and test it in copy_file_range01.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
 1 file changed, 42 insertions(+), 11 deletions(-)

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 a5bd5e7f7..aef626fce 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
@@ -24,7 +24,17 @@
 
 static int page_size;
 static int errcount, numcopies;
-static int fd_in, fd_out;
+static int fd_in, fd_out, cross_sup;
+char FILE_TARGET_PATH[40];
+
+static struct tcase {
+	char    *path;
+	int     flags;
+	char    *message;
+} tcases[] = {
+	{FILE_DEST_PATH,  0, "non cross-device"},
+	{FILE_MNTED_PATH, 1, "cross-device"},
+};
 
 static int check_file_content(const char *fname1, const char *fname2,
 	loff_t *off1, loff_t *off2, size_t len)
@@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 		to_copy -= TST_RET;
 	} while (to_copy > 0);
 
-	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
+	ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
 		off_in, off_out, len);
 	if (ret) {
 		tst_res(TFAIL, "file contents do not match");
@@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 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);
+	fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
 }
 
 static void close_files(void)
@@ -163,9 +173,18 @@ static void close_files(void)
 		SAFE_CLOSE(fd_in);
 }
 
-static void copy_file_range_verify(void)
+static void copy_file_range_verify(unsigned int n)
 {
 	int i, j, k;
+	struct tcase *tc = &tcases[n];
+
+	if (tc->flags && !cross_sup) {
+		tst_res(TCONF,
+			"copy_file_range doesn't support cross-device, skip it");
+		return;
+	}
+
+	strcpy(FILE_TARGET_PATH, tc->path);
 
 	errcount = numcopies = 0;
 	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
@@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
 
 	if (errcount == 0)
 		tst_res(TPASS,
-			"copy_file_range completed all %d copy jobs successfully!",
-			numcopies);
+			"%s copy_file_range completed all %d copy jobs successfully!",
+			tc->message, numcopies);
 	else
-		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
-				errcount, numcopies);
+		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
+			tc->message, errcount, numcopies);
 }
 
 static void setup(void)
 {
-	int i, fd;
+	int i, fd, fd1;
 
 	syscall_info();
 
 	page_size = getpagesize();
-
+	cross_sup = 1;
 	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, CONTSIZE);
+
+	fd1 = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
+	TEST(sys_copy_file_range(fd, 0, fd1, 0, CONTSIZE, 0));
+	if (TST_RET == -1)
+		cross_sup = 0;
+
+	SAFE_CLOSE(fd1);
+	remove(FILE_MNTED_PATH);
 	SAFE_CLOSE(fd);
 }
 
@@ -220,7 +247,11 @@ static void cleanup(void)
 static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
 	.needs_tmpdir = 1,
-	.test_all = copy_file_range_verify,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.test = copy_file_range_verify,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
  2019-07-10  7:18             ` [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-10  7:18             ` Yang Xu
  2019-07-10  7:57               ` Amir Goldstein
  2019-07-10  7:47             ` [LTP] [PATCH v3 " Amir Goldstein
  2 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-10  7:18 UTC (permalink / raw)
  To: ltp

Since Amir patch[1] for copy_file_range has been merged into linux-xfs for
next branch, I want to add test for swapfile, immutable file, bounds in ltp.
Also, add test for block,char,pipe dev and remove EXDEV test(5.3 will relax
the cross-device constraint[2]).  I follow xfstests code[3][4][5].

[1]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=96e6e8f
[2]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=5dae222
[3]https://patchwork.kernel.org/patch/10971759/
[4]https://patchwork.kernel.org/patch/10971747/
[5]https://patchwork.kernel.org/patch/10961421/

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../copy_file_range/copy_file_range.h         |  20 ++-
 .../copy_file_range/copy_file_range02.c       | 142 +++++++++++++++---
 2 files changed, 141 insertions(+), 21 deletions(-)

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..2a9eec75d 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,6 +9,8 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
 #include "lapi/syscalls.h"
 
 #define TEST_VARIANTS	2
@@ -18,11 +20,27 @@
 #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
+#define FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_BLKDEV    "file_blk"
+#define FILE_CHRDEV    "/dev/null"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
 
+#if __WORDSIZE == 64
+	#define MAX_LFS_FILESIZE        ((loff_t)LLONG_MAX)
+#else
+	#define MAX_LFS_FILESIZE        ((loff_t)ULONG_MAX << PAGE_SHIFT)
+#endif
+
+#define MAX_LEN   MAX_LFS_FILESIZE
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
+
 static void syscall_info(void)
 {
 	switch (tst_variant) {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..abe6d5751 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     16EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond 8EiB ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,78 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
+static int loop_devn;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
+	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
+		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
+		return;
+	}
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,14 +134,27 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (loop_devn >= 0)
+		SAFE_UNLINK(FILE_BLKDEV);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
@@ -93,16 +164,47 @@ static void setup(void)
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 
+	loop_devn = find_free_loopdev();
+	if (loop_devn >= 0)
+		SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn));
+
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
+
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+	fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600);
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +215,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-09 10:06         ` Amir Goldstein
  2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
@ 2019-07-10  7:32           ` Yang Xu
  1 sibling, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-10  7:32 UTC (permalink / raw)
  To: ltp

on 2019/07/09 18:06, Amir Goldstein wrote:

> On Tue, Jul 9, 2019 at 9:57 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> on 2019/07/08 23:17, Amir Goldstein wrote:
>>
>>> On Mon, Jul 8, 2019 at 1:46 PM Yang Xu<xuyang2018.jy@cn.fujitsu.com>   wrote:
>>>> Since Amir path for copy_file_range has been merged into linux-xfs,
>>>> I add test for swapfile, immutable file, bounds in ltp.  Also, add test
>>>> for block char pipe dev and remove EXDEV test(5.3 will relax the cross-device
>>>> constraint[2]).  I follow xfstests code[3][4][5] and increase it .
>>>>
>>>> [1]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=5dae222a5ff0c269730393018a5539cc970a4726
>>>> [2]https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/commit/?h=for-next-5.3&id=96e6e8f4a68df2d94800311163faa67124df24e5
>>>> [3]https://patchwork.kernel.org/patch/10971759/
>>>> [4]https://patchwork.kernel.org/patch/10971747/
>>>> [5]https://patchwork.kernel.org/patch/10961421/
>>>>
>>>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>>>> ---
>>>>    .../copy_file_range/copy_file_range.h         |  11 +-
>>>>    .../copy_file_range/copy_file_range02.c       | 139 +++++++++++++++---
>>>>    2 files changed, 130 insertions(+), 20 deletions(-)
>>>>
>>>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>>>> index b6d132978..f9e2565d9 100644
>>>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>>>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>>>> @@ -9,6 +9,7 @@
>>>>
>>>>    #include<stdbool.h>
>>>>    #include<unistd.h>
>>>> +#include<sys/sysmacros.h>
>>>>    #include "lapi/syscalls.h"
>>>>
>>>>    #define TEST_VARIANTS  2
>>>> @@ -18,10 +19,18 @@
>>>>    #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 FILE_IMMUTABLE_PATH "file_immutable"
>>>> +#define FILE_SWAP_PATH "file_swap"
>>>> +#define FILE_BLKDEV    "file_blk"
>>>> +#define FILE_CHRDEV    "file_chr"
>>>> +#define FILE_FIFO      "file_fifo"
>>>> +#define FILE_COPY_PATH  "file_copy"
>>>>
>>>>    #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>>>>    #define CONTSIZE       (sizeof(CONTENT) - 1)
>>>> +#define MAX_LEN   ((long long)(~0ULL>>   1))
>>>> +#define MIN_OFF   65537
>>>> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
>>> In the xfstest the value of MAX_OFF is ((1ULL<<   63) - MIN_OFF)
>>> Not sure why it was changed here?
>> Because the LONG LONG max value in kernel linux/limit.h is defined as" #define LLONG_MAX  ((long long)(~0ULL>>   1))".
>> I think it is a common usage.   If you don't like this way, I will use the xfstests vaule.
> No it makes sense. VFS max size is larger than XFS max size and
> I think btrfs is limited for the VFS max.
>
> Maybe it is better to define MAX_LFS_FILESIZE if it is not defined
> in some ltp header file and #define MAX_LEN MAX_LFS_FILESIZE
> leaving comments where due.
>
> Also, I now wonder if running this test on 32bit kernel and with test
> compiled for 32bit will yield the expected errors?
Hi Amir

I have sent a v3 patch. I split it into 3 patch.
lib: alter find_free_loopdev()
syscalls/copy_file_range01: add cross-device test
syscalls/copy_file_range02: increase coverage and remove EXDEV test

I don't have 32bit machine or vm.   It takes some time.  Please wait.
ps: If someone can help to test it, it will be great.

Thanks,
Yang Xu

> Thanks,
> Amir.
>
>
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev()
  2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
  2019-07-10  7:18             ` [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
  2019-07-10  7:18             ` [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-10  7:47             ` Amir Goldstein
  2 siblings, 0 replies; 86+ messages in thread
From: Amir Goldstein @ 2019-07-10  7:47 UTC (permalink / raw)
  To: ltp

On Wed, Jul 10, 2019 at 10:18 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Alter find_free_loopdev() to return the free loopdev minor
> (and -1 for no free loopdev) and then WE can safely use the
> minor number that find_free_loopdev() returned in test cases.
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> ---
>  doc/test-writing-guidelines.txt |  9 +++++++++
>  include/tst_device.h            |  6 ++++++
>  lib/tst_device.c                | 12 ++++++------
>  3 files changed, 21 insertions(+), 6 deletions(-)
>
> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
> index c6d4e001d..887801e68 100644
> --- a/doc/test-writing-guidelines.txt
> +++ b/doc/test-writing-guidelines.txt
> @@ -1045,6 +1045,15 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>  -------------------------------------------------------------------------------
>  #include "tst_test.h"
>
> +int find_free_loopdev();
> +-------------------------------------------------------------------------------
> +This function finds a free loopdev for use and returns the free loopdev minor(-1
> +for no free loopdev).
> +
> +[source,c]
> +-------------------------------------------------------------------------------
> +#include "tst_test.h"
> +
>  unsigned long tst_dev_bytes_written(const char *dev);
>  -------------------------------------------------------------------------------
>
> diff --git a/include/tst_device.h b/include/tst_device.h
> index 61902b7e0..8953b0828 100644
> --- a/include/tst_device.h
> +++ b/include/tst_device.h
> @@ -44,6 +44,12 @@ int tst_umount(const char *path);
>   */
>  int tst_clear_device(const char *dev);
>
> +/*
> + * Finds a free loop device for use and returns the free loopdev minor(-1 for no
> + * free loopdev).
> + */
> +int find_free_loopdev(void);
> +
>  /*
>   * Reads test block device stat file and returns the bytes written since the
>   * last call of this function.
> diff --git a/lib/tst_device.c b/lib/tst_device.c
> index 65fcc1337..3b87dd1f1 100644
> --- a/lib/tst_device.c
> +++ b/lib/tst_device.c
> @@ -68,7 +68,7 @@ static int set_dev_path(int dev)
>         return 0;
>  }
>
> -static int find_free_loopdev(void)
> +int find_free_loopdev(void)
>  {
>         int ctl_fd, dev_fd, rc, i;
>         struct loop_info loopinfo;
> @@ -82,10 +82,10 @@ static int find_free_loopdev(void)
>                 if (rc >= 0) {
>                         set_dev_path(rc);
>                         tst_resm(TINFO, "Found free device '%s'", dev_path);
> -                       return 0;
> +                       return rc;
>                 }
>                 tst_resm(TINFO, "Couldn't find free loop device");
> -               return 1;
> +               return -1;
>         }
>
>         switch (errno) {
> @@ -121,7 +121,7 @@ static int find_free_loopdev(void)
>                                 continue;
>                         tst_resm(TINFO, "Found free device '%s'", dev_path);
>                         close(dev_fd);
> -                       return 0;
> +                       return i;
>                 }
>
>                 close(dev_fd);
> @@ -129,7 +129,7 @@ static int find_free_loopdev(void)
>
>         tst_resm(TINFO, "No free devices found");
>
> -       return 1;
> +       return -1;
>  }
>
>  static int attach_device(const char *dev, const char *file)
> @@ -274,7 +274,7 @@ const char *tst_acquire_device__(unsigned int size)
>                 return NULL;
>         }
>
> -       if (find_free_loopdev())
> +       if (find_free_loopdev() == -1)
>                 return NULL;
>
>         if (attach_device(dev_path, DEV_FILE))
> --
> 2.18.1
>
>
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10  7:18             ` [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-10  7:50               ` Amir Goldstein
  2019-07-10  8:22                 ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-10  7:50 UTC (permalink / raw)
  To: ltp

On Wed, Jul 10, 2019 at 10:18 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Amir has relaxed cross-device constraint since commit(vfs: allow
> copy_file_range to copy across devices), I think we can remove it
> in copy_file_range02 and test it in copy_file_range01.
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
>  1 file changed, 42 insertions(+), 11 deletions(-)
>
> 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 a5bd5e7f7..aef626fce 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> @@ -24,7 +24,17 @@
>
>  static int page_size;
>  static int errcount, numcopies;
> -static int fd_in, fd_out;
> +static int fd_in, fd_out, cross_sup;
> +char FILE_TARGET_PATH[40];
> +
> +static struct tcase {
> +       char    *path;
> +       int     flags;
> +       char    *message;
> +} tcases[] = {
> +       {FILE_DEST_PATH,  0, "non cross-device"},
> +       {FILE_MNTED_PATH, 1, "cross-device"},
> +};
>
>  static int check_file_content(const char *fname1, const char *fname2,
>         loff_t *off1, loff_t *off2, size_t len)
> @@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>                 to_copy -= TST_RET;
>         } while (to_copy > 0);
>
> -       ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
> +       ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
>                 off_in, off_out, len);
>         if (ret) {
>                 tst_res(TFAIL, "file contents do not match");
> @@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>  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);
> +       fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
>  }
>
>  static void close_files(void)
> @@ -163,9 +173,18 @@ static void close_files(void)
>                 SAFE_CLOSE(fd_in);
>  }
>
> -static void copy_file_range_verify(void)
> +static void copy_file_range_verify(unsigned int n)
>  {
>         int i, j, k;
> +       struct tcase *tc = &tcases[n];
> +
> +       if (tc->flags && !cross_sup) {
> +               tst_res(TCONF,
> +                       "copy_file_range doesn't support cross-device, skip it");
> +               return;
> +       }
> +
> +       strcpy(FILE_TARGET_PATH, tc->path);
>
>         errcount = numcopies = 0;
>         size_t len_arr[]        = {11, page_size-1, page_size, page_size+1};
> @@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
>
>         if (errcount == 0)
>                 tst_res(TPASS,
> -                       "copy_file_range completed all %d copy jobs successfully!",
> -                       numcopies);
> +                       "%s copy_file_range completed all %d copy jobs successfully!",
> +                       tc->message, numcopies);
>         else
> -               tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
> -                               errcount, numcopies);
> +               tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
> +                       tc->message, errcount, numcopies);
>  }
>
>  static void setup(void)
>  {
> -       int i, fd;
> +       int i, fd, fd1;
>
>         syscall_info();
>
>         page_size = getpagesize();
> -
> +       cross_sup = 1;
>         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, CONTSIZE);
> +
> +       fd1 = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> +       TEST(sys_copy_file_range(fd, 0, fd1, 0, CONTSIZE, 0));
> +       if (TST_RET == -1)

I would restrict TCONF to errno == EXDEV.
Otherwise, a proper test failure is in order IMO.

> +               cross_sup = 0;
> +
> +       SAFE_CLOSE(fd1);
> +       remove(FILE_MNTED_PATH);
>         SAFE_CLOSE(fd);
>  }
>
> @@ -220,7 +247,11 @@ static void cleanup(void)
>  static struct tst_test test = {
>         .setup = setup,
>         .cleanup = cleanup,
> +       .tcnt = ARRAY_SIZE(tcases),
>         .needs_tmpdir = 1,
> -       .test_all = copy_file_range_verify,
> +       .mount_device = 1,
> +       .mntpoint = MNTPOINT,
> +       .all_filesystems = 1,
> +       .test = copy_file_range_verify,
>         .test_variants = TEST_VARIANTS,
>  };
> --
> 2.18.1
>
>
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-10  7:18             ` [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-10  7:57               ` Amir Goldstein
  2019-07-10  9:31                 ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-10  7:57 UTC (permalink / raw)
  To: ltp

On Wed, Jul 10, 2019 at 10:18 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Since Amir patch[1] for copy_file_range has been merged into linux-xfs for
> next branch, I want to add test for swapfile, immutable file, bounds in ltp.
> Also, add test for block,char,pipe dev and remove EXDEV test(5.3 will relax
> the cross-device constraint[2]).  I follow xfstests code[3][4][5].
>
> [1]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=96e6e8f
> [2]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=5dae222
> [3]https://patchwork.kernel.org/patch/10971759/
> [4]https://patchwork.kernel.org/patch/10971747/
> [5]https://patchwork.kernel.org/patch/10961421/
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

A few documentation nits below, otherwise you may add:

Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> ---
>  .../copy_file_range/copy_file_range.h         |  20 ++-
>  .../copy_file_range/copy_file_range02.c       | 142 +++++++++++++++---
>  2 files changed, 141 insertions(+), 21 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> index b6d132978..2a9eec75d 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -9,6 +9,8 @@
>
>  #include <stdbool.h>
>  #include <unistd.h>
> +#include <sys/sysmacros.h>
> +#include <limits.h>
>  #include "lapi/syscalls.h"
>
>  #define TEST_VARIANTS  2
> @@ -18,11 +20,27 @@
>  #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
> +#define FILE_IMMUTABLE_PATH "file_immutable"
> +#define FILE_SWAP_PATH "file_swap"
> +#define FILE_BLKDEV    "file_blk"
> +#define FILE_CHRDEV    "/dev/null"
> +#define FILE_FIFO      "file_fifo"
> +#define FILE_COPY_PATH  "file_copy"
>
>  #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>  #define CONTSIZE       (sizeof(CONTENT) - 1)
>

Worth a comment where of file this was copied from
and might be better to put it in some common header file

> +#if __WORDSIZE == 64
> +       #define MAX_LFS_FILESIZE        ((loff_t)LLONG_MAX)
> +#else
> +       #define MAX_LFS_FILESIZE        ((loff_t)ULONG_MAX << PAGE_SHIFT)
> +#endif
> +
> +#define MAX_LEN   MAX_LFS_FILESIZE
> +#define MIN_OFF   65537
> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
> +
>  static void syscall_info(void)
>  {
>         switch (tst_variant) {
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 07c0207c2..abe6d5751 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -10,15 +10,25 @@
>   *
>   * 1) Try to copy contents to file open as readonly
>   *    -> EBADF
> - * 2) Try to copy contents to file on different mounted
> - *    filesystem -> EXDEV
> - * 3) Try to copy contents to directory -> EISDIR
> - * 4) Try to copy contents to a file opened with the
> + * 2) Try to copy contents to directory -> EISDIR
> + * 3) Try to copy contents to a file opened with the
>   *    O_APPEND flag -> EBADF
> - * 5) Try to copy contents to closed filedescriptor
> + * 4) Try to copy contents to closed filedescriptor
>   *    -> EBADF
> - * 6) Try to copy contents with invalid 'flags' value
> + * 5) Try to copy contents with invalid 'flags' value
>   *    -> EINVAL
> + * 6) Try to copy contents to a file chattred with +i
> + *    flag -> EPERM
> + * 7) Try to copy contents to a swapfile ->ETXTBSY
> + * 8) Try to copy contents to the samefile with overlapping
> + *    ->EINVAL
> + * 9) Try to copy contents to a blkdev ->EINVAL
> + * 10) Try to copy contents to a chardev ->EINVAL
> + * 11) Try to copy contents to a FIFO ->EINVAL
> + * 12) Try to copy contents to a file with length beyond
> + *     16EiB wraps around 0 -> EOVERFLOW

Rephrase for description to be correct also on 32bit
BTW, I don't think current definition of 2*MAX_LEN
actually overflows on 32bit?

> + * 13) Try to copy contents to a file with target file range
> + *     beyond 8EiB ->EFBIG

Rephrase: beyond maximum supported file size

>   */
>
>  #define _GNU_SOURCE
> @@ -29,30 +39,78 @@
>  static int fd_src;
>  static int fd_dest;
>  static int fd_rdonly;
> -static int fd_mnted;
>  static int fd_dir;
>  static int fd_closed;
>  static int fd_append;
> +static int fd_immutable;
> +static int fd_swapfile;
> +static int fd_dup;
> +static int fd_blkdev;
> +static int fd_chrdev;
> +static int fd_fifo;
> +static int fd_copy;
> +
> +static int chattr_i_nsup;
> +static int swap_nsup;
> +static int loop_devn;
>
>  static struct tcase {
>         int     *copy_to_fd;
>         int     flags;
>         int     exp_err;
> +       loff_t  dst;
> +       loff_t     len;
>  } tcases[] = {
> -       {&fd_rdonly,    0,      EBADF},
> -       {&fd_mnted,     0,      EXDEV},
> -       {&fd_dir,       0,      EISDIR},
> -       {&fd_append,    0,      EBADF},
> -       {&fd_closed,    0,      EBADF},
> -       {&fd_dest,      -1,     EINVAL},
> +       {&fd_rdonly,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dir,       0,   EISDIR,     0,     CONTSIZE},
> +       {&fd_append,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_closed,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dest,      -1,  EINVAL,     0,     CONTSIZE},
> +       {&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
> +       {&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
> +       {&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
> +       {&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
> +       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
>
> +static int run_command(char *command, char *option, char *file)
> +{
> +       const char *const cmd[] = {command, option, file, NULL};
> +       int ret;
> +
> +       ret = tst_run_cmd(cmd, NULL, NULL, 1);
> +       switch (ret) {
> +       case 0:
> +       return 0;
> +       case 255:
> +               tst_res(TCONF, "%s binary not installed", command);
> +       return 1;
> +       default:
> +               tst_res(TCONF, "%s exited with %i", command, ret);
> +       return 2;
> +       }
> +}
> +
>  static void verify_copy_file_range(unsigned int n)
>  {
>         struct tcase *tc = &tcases[n];
> -
> +       if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
> +               tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
> +               return;
> +       }
> +       if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
> +               tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
> +               return;
> +       }
> +       if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
> +               tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
> +               return;
> +       }
>         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
> -                               0, CONTSIZE, tc->flags));
> +                               &tc->dst, tc->len, tc->flags));
>
>         if (TST_RET == -1) {
>                 if (tc->exp_err == TST_ERR) {
> @@ -76,14 +134,27 @@ static void cleanup(void)
>                 SAFE_CLOSE(fd_append);
>         if (fd_dir > 0)
>                 SAFE_CLOSE(fd_dir);
> -       if (fd_mnted > 0)
> -               SAFE_CLOSE(fd_mnted);
>         if (fd_rdonly > 0)
>                 SAFE_CLOSE(fd_rdonly);
>         if (fd_dest > 0)
>                 SAFE_CLOSE(fd_dest);
>         if (fd_src > 0)
>                 SAFE_CLOSE(fd_src);
> +       if (fd_immutable > 0) {
> +               run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
> +               SAFE_CLOSE(fd_immutable);
> +       }
> +       if (fd_swapfile > 0) {
> +               run_command("swapoff", FILE_SWAP_PATH, NULL);
> +               SAFE_CLOSE(fd_swapfile);
> +       }
> +       if (fd_dup > 0)
> +               SAFE_CLOSE(fd_dup);
> +       if (loop_devn >= 0)
> +               SAFE_UNLINK(FILE_BLKDEV);
> +       if (fd_copy > 0)
> +               SAFE_CLOSE(fd_copy);
> +       SAFE_UNLINK(FILE_FIFO);
>  }
>
>  static void setup(void)
> @@ -93,16 +164,47 @@ static void setup(void)
>         if (access(FILE_DIR_PATH, F_OK) == -1)
>                 SAFE_MKDIR(FILE_DIR_PATH, 0777);
>
> +       loop_devn = find_free_loopdev();
> +       if (loop_devn >= 0)
> +               SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn));
> +

This can raise eyebrows - worth a comment that we want to create a
non-instantiated loop device

> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
> +
>         fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>         fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>         fd_closed = -1;
>         fd_append = SAFE_OPEN(FILE_DEST_PATH,
>                         O_RDWR | O_CREAT | O_APPEND, 0664);
> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
> +       fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600);
> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
> +
> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
> +       close(fd_src);
> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
> +
> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
> +       chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> +
> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
> +               tst_res(TCONF, "Insufficient disk space to create swap file");
> +               swap_nsup = 3;
> +               return;
> +       }
> +
> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
> +               tst_res(TCONF, "Failed to create swapfile");
> +               swap_nsup = 4;
> +               return;
> +       }
>
> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
> +       swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
> +       swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
>  }
>
>  static struct tst_test test = {
> @@ -113,6 +215,6 @@ static struct tst_test test = {
>         .needs_root = 1,
>         .mount_device = 1,
>         .mntpoint = MNTPOINT,
> -       .dev_fs_type = "ext4",
> +       .all_filesystems = 1,
>         .test_variants = TEST_VARIANTS,
>  };
> --
> 2.18.1
>
>
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10  7:50               ` Amir Goldstein
@ 2019-07-10  8:22                 ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-10  8:22 UTC (permalink / raw)
  To: ltp

on 2019/07/10 15:50, Amir Goldstein wrote:

> On Wed, Jul 10, 2019 at 10:18 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> Amir has relaxed cross-device constraint since commit(vfs: allow
>> copy_file_range to copy across devices), I think we can remove it
>> in copy_file_range02 and test it in copy_file_range01.
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> ---
>>   .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
>>   1 file changed, 42 insertions(+), 11 deletions(-)
>>
>> 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 a5bd5e7f7..aef626fce 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
>> @@ -24,7 +24,17 @@
>>
>>   static int page_size;
>>   static int errcount, numcopies;
>> -static int fd_in, fd_out;
>> +static int fd_in, fd_out, cross_sup;
>> +char FILE_TARGET_PATH[40];
>> +
>> +static struct tcase {
>> +       char    *path;
>> +       int     flags;
>> +       char    *message;
>> +} tcases[] = {
>> +       {FILE_DEST_PATH,  0, "non cross-device"},
>> +       {FILE_MNTED_PATH, 1, "cross-device"},
>> +};
>>
>>   static int check_file_content(const char *fname1, const char *fname2,
>>          loff_t *off1, loff_t *off2, size_t len)
>> @@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>>                  to_copy -= TST_RET;
>>          } while (to_copy>  0);
>>
>> -       ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
>> +       ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
>>                  off_in, off_out, len);
>>          if (ret) {
>>                  tst_res(TFAIL, "file contents do not match");
>> @@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>>   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);
>> +       fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
>>   }
>>
>>   static void close_files(void)
>> @@ -163,9 +173,18 @@ static void close_files(void)
>>                  SAFE_CLOSE(fd_in);
>>   }
>>
>> -static void copy_file_range_verify(void)
>> +static void copy_file_range_verify(unsigned int n)
>>   {
>>          int i, j, k;
>> +       struct tcase *tc =&tcases[n];
>> +
>> +       if (tc->flags&&  !cross_sup) {
>> +               tst_res(TCONF,
>> +                       "copy_file_range doesn't support cross-device, skip it");
>> +               return;
>> +       }
>> +
>> +       strcpy(FILE_TARGET_PATH, tc->path);
>>
>>          errcount = numcopies = 0;
>>          size_t len_arr[]        = {11, page_size-1, page_size, page_size+1};
>> @@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
>>
>>          if (errcount == 0)
>>                  tst_res(TPASS,
>> -                       "copy_file_range completed all %d copy jobs successfully!",
>> -                       numcopies);
>> +                       "%s copy_file_range completed all %d copy jobs successfully!",
>> +                       tc->message, numcopies);
>>          else
>> -               tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
>> -                               errcount, numcopies);
>> +               tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
>> +                       tc->message, errcount, numcopies);
>>   }
>>
>>   static void setup(void)
>>   {
>> -       int i, fd;
>> +       int i, fd, fd1;
>>
>>          syscall_info();
>>
>>          page_size = getpagesize();
>> -
>> +       cross_sup = 1;
>>          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, CONTSIZE);
>> +
>> +       fd1 = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>> +       TEST(sys_copy_file_range(fd, 0, fd1, 0, CONTSIZE, 0));
>> +       if (TST_RET == -1)
> I would restrict TCONF to errno == EXDEV.
> Otherwise, a proper test failure is in order IMO.
>
Yes.  It also fails because of other situations. We should restrict TCONF to TST_ERR==EXDEV.

>> +               cross_sup = 0;
>> +
>> +       SAFE_CLOSE(fd1);
>> +       remove(FILE_MNTED_PATH);
>>          SAFE_CLOSE(fd);
>>   }
>>
>> @@ -220,7 +247,11 @@ static void cleanup(void)
>>   static struct tst_test test = {
>>          .setup = setup,
>>          .cleanup = cleanup,
>> +       .tcnt = ARRAY_SIZE(tcases),
>>          .needs_tmpdir = 1,
>> -       .test_all = copy_file_range_verify,
>> +       .mount_device = 1,
>> +       .mntpoint = MNTPOINT,
>> +       .all_filesystems = 1,
>> +       .test = copy_file_range_verify,
>>          .test_variants = TEST_VARIANTS,
>>   };
>> --
>> 2.18.1
>>
>>
>>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-10  7:57               ` Amir Goldstein
@ 2019-07-10  9:31                 ` Yang Xu
  2019-07-10 10:53                   ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-10  9:31 UTC (permalink / raw)
  To: ltp

on 2019/07/10 15:57, Amir Goldstein wrote:
> On Wed, Jul 10, 2019 at 10:18 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> Since Amir patch[1] for copy_file_range has been merged into linux-xfs for
>> next branch, I want to add test for swapfile, immutable file, bounds in ltp.
>> Also, add test for block,char,pipe dev and remove EXDEV test(5.3 will relax
>> the cross-device constraint[2]).  I follow xfstests code[3][4][5].
>>
>> [1]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=96e6e8f
>> [2]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=5dae222
>> [3]https://patchwork.kernel.org/patch/10971759/
>> [4]https://patchwork.kernel.org/patch/10971747/
>> [5]https://patchwork.kernel.org/patch/10961421/
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
> A few documentation nits below, otherwise you may add:
>
> Reviewed-by: Amir Goldstein<amir73il@gmail.com>
>
>> ---
>>   .../copy_file_range/copy_file_range.h         |  20 ++-
>>   .../copy_file_range/copy_file_range02.c       | 142 +++++++++++++++---
>>   2 files changed, 141 insertions(+), 21 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> index b6d132978..2a9eec75d 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
>> @@ -9,6 +9,8 @@
>>
>>   #include<stdbool.h>
>>   #include<unistd.h>
>> +#include<sys/sysmacros.h>
>> +#include<limits.h>
>>   #include "lapi/syscalls.h"
>>
>>   #define TEST_VARIANTS  2
>> @@ -18,11 +20,27 @@
>>   #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
>> +#define FILE_IMMUTABLE_PATH "file_immutable"
>> +#define FILE_SWAP_PATH "file_swap"
>> +#define FILE_BLKDEV    "file_blk"
>> +#define FILE_CHRDEV    "/dev/null"
>> +#define FILE_FIFO      "file_fifo"
>> +#define FILE_COPY_PATH  "file_copy"
>>
>>   #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>>   #define CONTSIZE       (sizeof(CONTENT) - 1)
>>
> Worth a comment where of file this was copied from
> and might be better to put it in some common header file
>
OK.  I will add a comment for this and move it  include/lapi/fs.h, as below:

diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 42cb4f9b2..d5a78e46b 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -35,4 +35,11 @@
  #define FS_NODUMP_FL      0x00000040 /* do not dump file */
  #endif

+/* Referred form linux kernel include/linux/fs.h */
+#if __WORDSIZE == 64
+        #define MAX_LFS_FILESIZE        ((loff_t)LLONG_MAX)
+#else
+        #define MAX_LFS_FILESIZE        ((loff_t)ULONG_MAX<<  PAGE_SHIFT)
+#endif
+
  #endif


>> +#if __WORDSIZE == 64
>> +       #define MAX_LFS_FILESIZE        ((loff_t)LLONG_MAX)
>> +#else
>> +       #define MAX_LFS_FILESIZE        ((loff_t)ULONG_MAX<<  PAGE_SHIFT)
>> +#endif
>> +
>> +#define MAX_LEN   MAX_LFS_FILESIZE
>> +#define MIN_OFF   65537
>> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
>> +
>>   static void syscall_info(void)
>>   {
>>          switch (tst_variant) {
>> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> index 07c0207c2..abe6d5751 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
>> @@ -10,15 +10,25 @@
>>    *
>>    * 1) Try to copy contents to file open as readonly
>>    *    ->  EBADF
>> - * 2) Try to copy contents to file on different mounted
>> - *    filesystem ->  EXDEV
>> - * 3) Try to copy contents to directory ->  EISDIR
>> - * 4) Try to copy contents to a file opened with the
>> + * 2) Try to copy contents to directory ->  EISDIR
>> + * 3) Try to copy contents to a file opened with the
>>    *    O_APPEND flag ->  EBADF
>> - * 5) Try to copy contents to closed filedescriptor
>> + * 4) Try to copy contents to closed filedescriptor
>>    *    ->  EBADF
>> - * 6) Try to copy contents with invalid 'flags' value
>> + * 5) Try to copy contents with invalid 'flags' value
>>    *    ->  EINVAL
>> + * 6) Try to copy contents to a file chattred with +i
>> + *    flag ->  EPERM
>> + * 7) Try to copy contents to a swapfile ->ETXTBSY
>> + * 8) Try to copy contents to the samefile with overlapping
>> + *    ->EINVAL
>> + * 9) Try to copy contents to a blkdev ->EINVAL
>> + * 10) Try to copy contents to a chardev ->EINVAL
>> + * 11) Try to copy contents to a FIFO ->EINVAL
>> + * 12) Try to copy contents to a file with length beyond
>> + *     16EiB wraps around 0 ->  EOVERFLOW
> Rephrase for description to be correct also on 32bit
> BTW, I don't think current definition of 2*MAX_LEN
> actually overflows on 32bit?
  in mm/filemap.c

     /* Ensure offsets don't wrap. */
+       if (pos_in + count<  pos_in || pos_out + count<  pos_out)
+               return -EOVERFLOW;

these variables are long long or uint64_t,  so we should set tc->len as ULLONG_MAX if we want to
trigger the EOVERFLOW on 32bit or 64bit.   as below

	static struct tcase {
		.....
	} tcases[] = {
		....
  	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
	.....

How about it?


>> + * 13) Try to copy contents to a file with target file range
>> + *     beyond 8EiB ->EFBIG
> Rephrase: beyond maximum supported file size
OK.
>>    */
>>
>>   #define _GNU_SOURCE
>> @@ -29,30 +39,78 @@
>>   static int fd_src;
>>   static int fd_dest;
>>   static int fd_rdonly;
>> -static int fd_mnted;
>>   static int fd_dir;
>>   static int fd_closed;
>>   static int fd_append;
>> +static int fd_immutable;
>> +static int fd_swapfile;
>> +static int fd_dup;
>> +static int fd_blkdev;
>> +static int fd_chrdev;
>> +static int fd_fifo;
>> +static int fd_copy;
>> +
>> +static int chattr_i_nsup;
>> +static int swap_nsup;
>> +static int loop_devn;
>>
>>   static struct tcase {
>>          int     *copy_to_fd;
>>          int     flags;
>>          int     exp_err;
>> +       loff_t  dst;
>> +       loff_t     len;
>>   } tcases[] = {
>> -       {&fd_rdonly,    0,      EBADF},
>> -       {&fd_mnted,     0,      EXDEV},
>> -       {&fd_dir,       0,      EISDIR},
>> -       {&fd_append,    0,      EBADF},
>> -       {&fd_closed,    0,      EBADF},
>> -       {&fd_dest,      -1,     EINVAL},
>> +       {&fd_rdonly,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_dir,       0,   EISDIR,     0,     CONTSIZE},
>> +       {&fd_append,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_closed,    0,   EBADF,      0,     CONTSIZE},
>> +       {&fd_dest,      -1,  EINVAL,     0,     CONTSIZE},
>> +       {&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
>> +       {&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
>> +       {&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
>> +       {&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
>> +       {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, 2*MAX_LEN},
>> +       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>>   };
>>
>> +static int run_command(char *command, char *option, char *file)
>> +{
>> +       const char *const cmd[] = {command, option, file, NULL};
>> +       int ret;
>> +
>> +       ret = tst_run_cmd(cmd, NULL, NULL, 1);
>> +       switch (ret) {
>> +       case 0:
>> +       return 0;
>> +       case 255:
>> +               tst_res(TCONF, "%s binary not installed", command);
>> +       return 1;
>> +       default:
>> +               tst_res(TCONF, "%s exited with %i", command, ret);
>> +       return 2;
>> +       }
>> +}
>> +
>>   static void verify_copy_file_range(unsigned int n)
>>   {
>>          struct tcase *tc =&tcases[n];
>> -
>> +       if (tc->copy_to_fd ==&fd_immutable&&  chattr_i_nsup) {
>> +               tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
>> +               return;
>> +       }
>> +       if (tc->copy_to_fd ==&fd_swapfile&&  swap_nsup) {
>> +               tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
>> +               return;
>> +       }
>> +       if (tc->copy_to_fd ==&fd_blkdev&&  loop_devn == -1) {
>> +               tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
>> +               return;
>> +       }
>>          TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
>> -                               0, CONTSIZE, tc->flags));
>> +&tc->dst, tc->len, tc->flags));
>>
>>          if (TST_RET == -1) {
>>                  if (tc->exp_err == TST_ERR) {
>> @@ -76,14 +134,27 @@ static void cleanup(void)
>>                  SAFE_CLOSE(fd_append);
>>          if (fd_dir>  0)
>>                  SAFE_CLOSE(fd_dir);
>> -       if (fd_mnted>  0)
>> -               SAFE_CLOSE(fd_mnted);
>>          if (fd_rdonly>  0)
>>                  SAFE_CLOSE(fd_rdonly);
>>          if (fd_dest>  0)
>>                  SAFE_CLOSE(fd_dest);
>>          if (fd_src>  0)
>>                  SAFE_CLOSE(fd_src);
>> +       if (fd_immutable>  0) {
>> +               run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
>> +               SAFE_CLOSE(fd_immutable);
>> +       }
>> +       if (fd_swapfile>  0) {
>> +               run_command("swapoff", FILE_SWAP_PATH, NULL);
>> +               SAFE_CLOSE(fd_swapfile);
>> +       }
>> +       if (fd_dup>  0)
>> +               SAFE_CLOSE(fd_dup);
>> +       if (loop_devn>= 0)
>> +               SAFE_UNLINK(FILE_BLKDEV);
>> +       if (fd_copy>  0)
>> +               SAFE_CLOSE(fd_copy);
>> +       SAFE_UNLINK(FILE_FIFO);
>>   }
>>
>>   static void setup(void)
>> @@ -93,16 +164,47 @@ static void setup(void)
>>          if (access(FILE_DIR_PATH, F_OK) == -1)
>>                  SAFE_MKDIR(FILE_DIR_PATH, 0777);
>>
>> +       loop_devn = find_free_loopdev();
>> +       if (loop_devn>= 0)
>> +               SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn));
>> +
> This can raise eyebrows - worth a comment that we want to create a
> non-instantiated loop device
OK. I wiil add a comment for this.

>> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
>> +
>>          fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
>> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>>          fd_closed = -1;
>>          fd_append = SAFE_OPEN(FILE_DEST_PATH,
>>                          O_RDWR | O_CREAT | O_APPEND, 0664);
>> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
>> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
>> +       fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600);
>> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
>> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
>> +
>> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
>> +       close(fd_src);
>> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
>> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
>> +
>> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
>> +       chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
>> +
>> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
>> +               tst_res(TCONF, "Insufficient disk space to create swap file");
>> +               swap_nsup = 3;
>> +               return;
>> +       }
>> +
>> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
>> +               tst_res(TCONF, "Failed to create swapfile");
>> +               swap_nsup = 4;
>> +               return;
>> +       }
>>
>> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
>> +       swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
>> +       swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
>>   }
>>
>>   static struct tst_test test = {
>> @@ -113,6 +215,6 @@ static struct tst_test test = {
>>          .needs_root = 1,
>>          .mount_device = 1,
>>          .mntpoint = MNTPOINT,
>> -       .dev_fs_type = "ext4",
>> +       .all_filesystems = 1,
>>          .test_variants = TEST_VARIANTS,
>>   };
>> --
>> 2.18.1
>>
>>
>>
>
> .
>




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-10  9:31                 ` Yang Xu
@ 2019-07-10 10:53                   ` Yang Xu
  2019-07-10 10:53                     ` [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
                                       ` (2 more replies)
  0 siblings, 3 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-10 10:53 UTC (permalink / raw)
  To: ltp

Alter find_free_loopdev() to return the free loopdev minor
(and -1 for no free loopdev) and then WE can safely use the
minor number that find_free_loopdev() returned in test cases.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 doc/test-writing-guidelines.txt |  9 +++++++++
 include/tst_device.h            |  6 ++++++
 lib/tst_device.c                | 12 ++++++------
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index c6d4e001d..887801e68 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1045,6 +1045,15 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
 -------------------------------------------------------------------------------
 #include "tst_test.h"
 
+int find_free_loopdev();
+-------------------------------------------------------------------------------
+This function finds a free loopdev for use and returns the free loopdev minor(-1
+for no free loopdev).
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
 unsigned long tst_dev_bytes_written(const char *dev);
 -------------------------------------------------------------------------------
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 61902b7e0..8953b0828 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -44,6 +44,12 @@ int tst_umount(const char *path);
  */
 int tst_clear_device(const char *dev);
 
+/*
+ * Finds a free loop device for use and returns the free loopdev minor(-1 for no
+ * free loopdev).
+ */
+int find_free_loopdev(void);
+
 /*
  * Reads test block device stat file and returns the bytes written since the
  * last call of this function.
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 65fcc1337..3b87dd1f1 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -68,7 +68,7 @@ static int set_dev_path(int dev)
 	return 0;
 }
 
-static int find_free_loopdev(void)
+int find_free_loopdev(void)
 {
 	int ctl_fd, dev_fd, rc, i;
 	struct loop_info loopinfo;
@@ -82,10 +82,10 @@ static int find_free_loopdev(void)
 		if (rc >= 0) {
 			set_dev_path(rc);
 			tst_resm(TINFO, "Found free device '%s'", dev_path);
-			return 0;
+			return rc;
 		}
 		tst_resm(TINFO, "Couldn't find free loop device");
-		return 1;
+		return -1;
 	}
 
 	switch (errno) {
@@ -121,7 +121,7 @@ static int find_free_loopdev(void)
 				continue;
 			tst_resm(TINFO, "Found free device '%s'", dev_path);
 			close(dev_fd);
-			return 0;
+			return i;
 		}
 
 		close(dev_fd);
@@ -129,7 +129,7 @@ static int find_free_loopdev(void)
 
 	tst_resm(TINFO, "No free devices found");
 
-	return 1;
+	return -1;
 }
 
 static int attach_device(const char *dev, const char *file)
@@ -274,7 +274,7 @@ const char *tst_acquire_device__(unsigned int size)
 		return NULL;
 	}
 
-	if (find_free_loopdev())
+	if (find_free_loopdev() == -1)
 		return NULL;
 
 	if (attach_device(dev_path, DEV_FILE))
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10 10:53                   ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Yang Xu
@ 2019-07-10 10:53                     ` Yang Xu
  2019-07-10 15:56                       ` Xiao Yang
  2019-07-10 10:53                     ` [LTP] [PATCH v4 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-10 13:57                     ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Cyril Hrubis
  2 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-10 10:53 UTC (permalink / raw)
  To: ltp

Amir has relaxed cross-device constraint since commit(vfs: allow
copy_file_range to copy across devices), I think we can remove it
in copy_file_range02 and test it in copy_file_range01.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
 1 file changed, 42 insertions(+), 11 deletions(-)

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 a5bd5e7f7..e1aa06c3e 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
@@ -24,7 +24,17 @@
 
 static int page_size;
 static int errcount, numcopies;
-static int fd_in, fd_out;
+static int fd_in, fd_out, cross_sup;
+char FILE_TARGET_PATH[40];
+
+static struct tcase {
+	char    *path;
+	int     flags;
+	char    *message;
+} tcases[] = {
+	{FILE_DEST_PATH,  0, "non cross-device"},
+	{FILE_MNTED_PATH, 1, "cross-device"},
+};
 
 static int check_file_content(const char *fname1, const char *fname2,
 	loff_t *off1, loff_t *off2, size_t len)
@@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 		to_copy -= TST_RET;
 	} while (to_copy > 0);
 
-	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
+	ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
 		off_in, off_out, len);
 	if (ret) {
 		tst_res(TFAIL, "file contents do not match");
@@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 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);
+	fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
 }
 
 static void close_files(void)
@@ -163,9 +173,18 @@ static void close_files(void)
 		SAFE_CLOSE(fd_in);
 }
 
-static void copy_file_range_verify(void)
+static void copy_file_range_verify(unsigned int n)
 {
 	int i, j, k;
+	struct tcase *tc = &tcases[n];
+
+	if (tc->flags && !cross_sup) {
+		tst_res(TCONF,
+			"copy_file_range doesn't support cross-device, skip it");
+		return;
+	}
+
+	strcpy(FILE_TARGET_PATH, tc->path);
 
 	errcount = numcopies = 0;
 	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
@@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
 
 	if (errcount == 0)
 		tst_res(TPASS,
-			"copy_file_range completed all %d copy jobs successfully!",
-			numcopies);
+			"%s copy_file_range completed all %d copy jobs successfully!",
+			tc->message, numcopies);
 	else
-		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
-				errcount, numcopies);
+		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
+			tc->message, errcount, numcopies);
 }
 
 static void setup(void)
 {
-	int i, fd;
+	int i, fd, fd_test;
 
 	syscall_info();
 
 	page_size = getpagesize();
-
+	cross_sup = 1;
 	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, CONTSIZE);
+
+	fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
+	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
+	if (TST_ERR == EXDEV)
+		cross_sup = 0;
+
+	SAFE_CLOSE(fd_test);
+	remove(FILE_MNTED_PATH);
 	SAFE_CLOSE(fd);
 }
 
@@ -220,7 +247,11 @@ static void cleanup(void)
 static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
 	.needs_tmpdir = 1,
-	.test_all = copy_file_range_verify,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.test = copy_file_range_verify,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-10 10:53                   ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Yang Xu
  2019-07-10 10:53                     ` [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-10 10:53                     ` Yang Xu
  2019-07-10 13:57                     ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Cyril Hrubis
  2 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-10 10:53 UTC (permalink / raw)
  To: ltp

Since Amir patch[1] for copy_file_range has been merged into linux-xfs for
next branch, I want to add swapfile, immutable file, bounds tests in ltp.
Also, add  block,char,pipe dev tests and remove EXDEV test(5.3 will relax
the cross-device constraint[2]). I follow xfstests code[3][4][5].

[1]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=96e6e8f
[2]https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git/commit/?h=for-next&id=5dae222
[3]https://patchwork.kernel.org/patch/10971759/
[4]https://patchwork.kernel.org/patch/10971747/
[5]https://patchwork.kernel.org/patch/10961421/

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 include/lapi/fs.h                             |   7 +
 .../copy_file_range/copy_file_range.h         |  14 +-
 .../copy_file_range/copy_file_range02.c       | 146 +++++++++++++++---
 3 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 42cb4f9b2..5cfdb5450 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -35,4 +35,11 @@
 #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
 #endif
 
+/* Referred form linux kernel include/linux/fs.h */
+#if __WORDSIZE == 64
+ #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
+#else
+ #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
+#endif
+
 #endif
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..aedfda966 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,7 +9,10 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
 #include "lapi/syscalls.h"
+#include "lapi/fs.h"
 
 #define TEST_VARIANTS	2
 
@@ -18,10 +21,19 @@
 #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
+#define FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_BLKDEV    "file_blk"
+#define FILE_CHRDEV    "/dev/null"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_LEN   MAX_LFS_FILESIZE
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..fabf16877 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     16EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond maximum supported file size ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,78 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
+static int loop_devn;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
+	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
+		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
+		return;
+	}
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,14 +134,27 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (loop_devn >= 0)
+		SAFE_UNLINK(FILE_BLKDEV);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
@@ -92,17 +163,52 @@ static void setup(void)
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
+	/*
+	 * find_free_loopdev() returns the free loopdev minor, we make a
+	 * non-instantiated loop device by using it, avoid overwriting its
+	 * content on used loopdev.
+	 */
+	loop_devn = find_free_loopdev();
+	if (loop_devn >= 0)
+		SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn));
+
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
 
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+	fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600);
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +219,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-10 10:53                   ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Yang Xu
  2019-07-10 10:53                     ` [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
  2019-07-10 10:53                     ` [LTP] [PATCH v4 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-10 13:57                     ` Cyril Hrubis
  2019-07-11  4:00                       ` Yang Xu
  2 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-10 13:57 UTC (permalink / raw)
  To: ltp

Hi!
> Alter find_free_loopdev() to return the free loopdev minor
> (and -1 for no free loopdev) and then WE can safely use the
> minor number that find_free_loopdev() returned in test cases.
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> ---
>  doc/test-writing-guidelines.txt |  9 +++++++++
>  include/tst_device.h            |  6 ++++++
>  lib/tst_device.c                | 12 ++++++------
>  3 files changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
> index c6d4e001d..887801e68 100644
> --- a/doc/test-writing-guidelines.txt
> +++ b/doc/test-writing-guidelines.txt
> @@ -1045,6 +1045,15 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>  -------------------------------------------------------------------------------
>  #include "tst_test.h"
>  
> +int find_free_loopdev();

Once this is exported as public API it should be prefixed with tst_.

> -static int find_free_loopdev(void)
> +int find_free_loopdev(void)
>  {
>  	int ctl_fd, dev_fd, rc, i;
>  	struct loop_info loopinfo;
> @@ -82,10 +82,10 @@ static int find_free_loopdev(void)
>  		if (rc >= 0) {
>  			set_dev_path(rc);
>  			tst_resm(TINFO, "Found free device '%s'", dev_path);
> -			return 0;
> +			return rc;
>  		}
>  		tst_resm(TINFO, "Couldn't find free loop device");
> -		return 1;
> +		return -1;
>  	}
>  
>  	switch (errno) {
> @@ -121,7 +121,7 @@ static int find_free_loopdev(void)
>  				continue;
>  			tst_resm(TINFO, "Found free device '%s'", dev_path);
>  			close(dev_fd);
> -			return 0;
> +			return i;
>  		}
>  
>  		close(dev_fd);
> @@ -129,7 +129,7 @@ static int find_free_loopdev(void)
>  
>  	tst_resm(TINFO, "No free devices found");
>  
> -	return 1;
> +	return -1;
>  }

This needs more changes than this.

The problem here is that the function modifies dev_path which is
returned by tst_acquire_device() so if you call this function after
tst_acquire_device() it will rewrite the dev_path which means that the
test would end up with wrong device path in tst_device->dev.

I guess that the easiest solution would be changing the function to get
buffer parameter which, when non-NULL, is filled with the path.

I.e. the function prototype would became:

int tst_find_free_loopdev(char *path, size_t path_len);

And we would pass the dev_path inside of the tst_device.c and NULL from
the copy_file_range() tests.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10 10:53                     ` [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-10 15:56                       ` Xiao Yang
  2019-07-11  6:18                         ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Xiao Yang @ 2019-07-10 15:56 UTC (permalink / raw)
  To: ltp

On 07/10/2019 06:53 PM, Yang Xu wrote:
> Amir has relaxed cross-device constraint since commit(vfs: allow
> copy_file_range to copy across devices), I think we can remove it
> in copy_file_range02 and test it in copy_file_range01.
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> ---
>   .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
>   1 file changed, 42 insertions(+), 11 deletions(-)
>
> 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 a5bd5e7f7..e1aa06c3e 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
> @@ -24,7 +24,17 @@
>   
>   static int page_size;
>   static int errcount, numcopies;
> -static int fd_in, fd_out;
> +static int fd_in, fd_out, cross_sup;
> +char FILE_TARGET_PATH[40];
> +
> +static struct tcase {
> +	char    *path;
> +	int     flags;
> +	char    *message;
> +} tcases[] = {
> +	{FILE_DEST_PATH,  0, "non cross-device"},
> +	{FILE_MNTED_PATH, 1, "cross-device"},
> +};
>   
>   static int check_file_content(const char *fname1, const char *fname2,
>   	loff_t *off1, loff_t *off2, size_t len)
> @@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>   		to_copy -= TST_RET;
>   	} while (to_copy > 0);
>   
> -	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
> +	ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
>   		off_in, off_out, len);
>   	if (ret) {
>   		tst_res(TFAIL, "file contents do not match");
> @@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
>   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);
> +	fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
Hi,

Why don't we remove the global FILE_TARGET_PATH by passing tc->path to 
open_files()?

>   }
>   
>   static void close_files(void)
> @@ -163,9 +173,18 @@ static void close_files(void)
>   		SAFE_CLOSE(fd_in);
>   }
>   
> -static void copy_file_range_verify(void)
> +static void copy_file_range_verify(unsigned int n)
>   {
>   	int i, j, k;
> +	struct tcase *tc = &tcases[n];
> +
> +	if (tc->flags && !cross_sup) {
> +		tst_res(TCONF,
> +			"copy_file_range doesn't support cross-device, skip it");
> +		return;
> +	}

Perhaps, we can remove the global cross_sup and check of EXDEV in 
setup() by passing tc->flag to one_test().

> +
> +	strcpy(FILE_TARGET_PATH, tc->path);
>   
>   	errcount = numcopies = 0;
>   	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
> @@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
>   
>   	if (errcount == 0)
>   		tst_res(TPASS,
> -			"copy_file_range completed all %d copy jobs successfully!",
> -			numcopies);
> +			"%s copy_file_range completed all %d copy jobs successfully!",
> +			tc->message, numcopies);
>   	else
> -		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
> -				errcount, numcopies);
> +		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
> +			tc->message, errcount, numcopies);
>   }
>   
>   static void setup(void)
>   {
> -	int i, fd;
> +	int i, fd, fd_test;
>   
>   	syscall_info();
>   
>   	page_size = getpagesize();
> -
> +	cross_sup = 1;
>   	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, CONTSIZE);
> +
> +	fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> +	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
> +	if (TST_ERR == EXDEV)
> +		cross_sup = 0;
> +
> +	SAFE_CLOSE(fd_test);
> +	remove(FILE_MNTED_PATH);
Is it necessary to remove it?

Best Regards,
Xiao Yang
>   	SAFE_CLOSE(fd);
>   }
>   
> @@ -220,7 +247,11 @@ static void cleanup(void)
>   static struct tst_test test = {
>   	.setup = setup,
>   	.cleanup = cleanup,
> +	.tcnt = ARRAY_SIZE(tcases),
>   	.needs_tmpdir = 1,
> -	.test_all = copy_file_range_verify,
> +	.mount_device = 1,
> +	.mntpoint = MNTPOINT,
> +	.all_filesystems = 1,
> +	.test = copy_file_range_verify,
>   	.test_variants = TEST_VARIANTS,
>   };



^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-10 13:57                     ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Cyril Hrubis
@ 2019-07-11  4:00                       ` Yang Xu
  2019-07-11 12:51                         ` Cyril Hrubis
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-11  4:00 UTC (permalink / raw)
  To: ltp


> Hi!
>> Alter find_free_loopdev() to return the free loopdev minor
>> (and -1 for no free loopdev) and then WE can safely use the
>> minor number that find_free_loopdev() returned in test cases.
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> Reviewed-by: Amir Goldstein<amir73il@gmail.com>
>> ---
>>   doc/test-writing-guidelines.txt |  9 +++++++++
>>   include/tst_device.h            |  6 ++++++
>>   lib/tst_device.c                | 12 ++++++------
>>   3 files changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
>> index c6d4e001d..887801e68 100644
>> --- a/doc/test-writing-guidelines.txt
>> +++ b/doc/test-writing-guidelines.txt
>> @@ -1045,6 +1045,15 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>>   -------------------------------------------------------------------------------
>>   #include "tst_test.h"
>>
>> +int find_free_loopdev();
> Once this is exported as public API it should be prefixed with tst_.
>
OK.

>> -static int find_free_loopdev(void)
>> +int find_free_loopdev(void)
>>   {
>>   	int ctl_fd, dev_fd, rc, i;
>>   	struct loop_info loopinfo;
>> @@ -82,10 +82,10 @@ static int find_free_loopdev(void)
>>   		if (rc>= 0) {
>>   			set_dev_path(rc);
>>   			tst_resm(TINFO, "Found free device '%s'", dev_path);
>> -			return 0;
>> +			return rc;
>>   		}
>>   		tst_resm(TINFO, "Couldn't find free loop device");
>> -		return 1;
>> +		return -1;
>>   	}
>>
>>   	switch (errno) {
>> @@ -121,7 +121,7 @@ static int find_free_loopdev(void)
>>   				continue;
>>   			tst_resm(TINFO, "Found free device '%s'", dev_path);
>>   			close(dev_fd);
>> -			return 0;
>> +			return i;
>>   		}
>>
>>   		close(dev_fd);
>> @@ -129,7 +129,7 @@ static int find_free_loopdev(void)
>>
>>   	tst_resm(TINFO, "No free devices found");
>>
>> -	return 1;
>> +	return -1;
>>   }
> This needs more changes than this.
>
> The problem here is that the function modifies dev_path which is
> returned by tst_acquire_device() so if you call this function after
> tst_acquire_device() it will rewrite the dev_path which means that the
> test would end up with wrong device path in tst_device->dev.
>
> I guess that the easiest solution would be changing the function to get
> buffer parameter which, when non-NULL, is filled with the path.
>
> I.e. the function prototype would became:
>
> int tst_find_free_loopdev(char *path, size_t path_len);
>
> And we would pass the dev_path inside of the tst_device.c and NULL from
> the copy_file_range() tests.
Hi Cyril

This is a good comment. But I doubt why we don't use a set_devpath_flag todistinguish it.
Or you have a future plan(in different directory ,/dev,/dev/loop/,/dev/block)?

Thanks
Yang Xu





^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-10 15:56                       ` Xiao Yang
@ 2019-07-11  6:18                         ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-11  6:18 UTC (permalink / raw)
  To: ltp

on 2019/07/10 23:56, Xiao Yang wrote:

> On 07/10/2019 06:53 PM, Yang Xu wrote:
>> Amir has relaxed cross-device constraint since commit(vfs: allow
>> copy_file_range to copy across devices), I think we can remove it
>> in copy_file_range02 and test it in copy_file_range01.
>>
>> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
>> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
>> ---
>>   .../copy_file_range/copy_file_range01.c       | 53 +++++++++++++++----
>>   1 file changed, 42 insertions(+), 11 deletions(-)
>>
>> 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 a5bd5e7f7..e1aa06c3e 100644
>> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
>> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
>> @@ -24,7 +24,17 @@
>>     static int page_size;
>>   static int errcount, numcopies;
>> -static int fd_in, fd_out;
>> +static int fd_in, fd_out, cross_sup;
>> +char FILE_TARGET_PATH[40];
>> +
>> +static struct tcase {
>> +    char    *path;
>> +    int     flags;
>> +    char    *message;
>> +} tcases[] = {
>> +    {FILE_DEST_PATH,  0, "non cross-device"},
>> +    {FILE_MNTED_PATH, 1, "cross-device"},
>> +};
>>     static int check_file_content(const char *fname1, const char 
>> *fname2,
>>       loff_t *off1, loff_t *off2, size_t len)
>> @@ -131,7 +141,7 @@ static void test_one(size_t len, loff_t *off_in, 
>> loff_t *off_out)
>>           to_copy -= TST_RET;
>>       } while (to_copy > 0);
>>   -    ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
>> +    ret = check_file_content(FILE_SRC_PATH, FILE_TARGET_PATH,
>>           off_in, off_out, len);
>>       if (ret) {
>>           tst_res(TFAIL, "file contents do not match");
>> @@ -152,7 +162,7 @@ static void test_one(size_t len, loff_t *off_in, 
>> loff_t *off_out)
>>   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);
>> +    fd_out = SAFE_OPEN(FILE_TARGET_PATH, O_CREAT | O_WRONLY | 
>> O_TRUNC, 0644);
> Hi,
>
> Why don't we remove the global FILE_TARGET_PATH by passing tc->path to 
> open_files()?
OK. I will remove it and pass tc->path to open_files() ,test_one();

>
>>   }
>>     static void close_files(void)
>> @@ -163,9 +173,18 @@ static void close_files(void)
>>           SAFE_CLOSE(fd_in);
>>   }
>>   -static void copy_file_range_verify(void)
>> +static void copy_file_range_verify(unsigned int n)
>>   {
>>       int i, j, k;
>> +    struct tcase *tc = &tcases[n];
>> +
>> +    if (tc->flags && !cross_sup) {
>> +        tst_res(TCONF,
>> +            "copy_file_range doesn't support cross-device, skip it");
>> +        return;
>> +    }
>
> Perhaps, we can remove the global cross_sup and check of EXDEV in 
> setup() by passing tc->flag to one_test().
OK. I will use tc->flag in setup,  flag =2 is equal to TCONF(doesn't support cross-dev).

>
>> +
>> +    strcpy(FILE_TARGET_PATH, tc->path);
>>         errcount = numcopies = 0;
>>       size_t len_arr[]    = {11, page_size-1, page_size, page_size+1};
>> @@ -190,25 +209,33 @@ static void copy_file_range_verify(void)
>>         if (errcount == 0)
>>           tst_res(TPASS,
>> -            "copy_file_range completed all %d copy jobs successfully!",
>> -            numcopies);
>> +            "%s copy_file_range completed all %d copy jobs 
>> successfully!",
>> +            tc->message, numcopies);
>>       else
>> -        tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
>> -                errcount, numcopies);
>> +        tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
>> +            tc->message, errcount, numcopies);
>>   }
>>     static void setup(void)
>>   {
>> -    int i, fd;
>> +    int i, fd, fd_test;
>>         syscall_info();
>>         page_size = getpagesize();
>> -
>> +    cross_sup = 1;
>>       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, CONTSIZE);
>> +
>> +    fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>> +    TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
>> +    if (TST_ERR == EXDEV)
>> +        cross_sup = 0;
>> +
>> +    SAFE_CLOSE(fd_test);
>> +    remove(FILE_MNTED_PATH);
> Is it necessary to remove it?
>
I want to test on a clean environment, like FILE_DEST_PATH.
> Best Regards,
> Xiao Yang
>>       SAFE_CLOSE(fd);
>>   }
>>   @@ -220,7 +247,11 @@ static void cleanup(void)
>>   static struct tst_test test = {
>>       .setup = setup,
>>       .cleanup = cleanup,
>> +    .tcnt = ARRAY_SIZE(tcases),
>>       .needs_tmpdir = 1,
>> -    .test_all = copy_file_range_verify,
>> +    .mount_device = 1,
>> +    .mntpoint = MNTPOINT,
>> +    .all_filesystems = 1,
>> +    .test = copy_file_range_verify,
>>       .test_variants = TEST_VARIANTS,
>>   };
>
>
>
>
> .
>



^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-11  4:00                       ` Yang Xu
@ 2019-07-11 12:51                         ` Cyril Hrubis
  2019-07-12  5:25                           ` Yang Xu
  2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
  0 siblings, 2 replies; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-11 12:51 UTC (permalink / raw)
  To: ltp

Hi!
> > This needs more changes than this.
> >
> > The problem here is that the function modifies dev_path which is
> > returned by tst_acquire_device() so if you call this function after
> > tst_acquire_device() it will rewrite the dev_path which means that the
> > test would end up with wrong device path in tst_device->dev.
> >
> > I guess that the easiest solution would be changing the function to get
> > buffer parameter which, when non-NULL, is filled with the path.
> >
> > I.e. the function prototype would became:
> >
> > int tst_find_free_loopdev(char *path, size_t path_len);
> >
> > And we would pass the dev_path inside of the tst_device.c and NULL from
> > the copy_file_range() tests.
> Hi Cyril
> 
> This is a good comment. But I doubt why we don't use a set_devpath_flag todistinguish it.
> Or you have a future plan(in different directory ,/dev,/dev/loop/,/dev/block)?

Well you can add a flag to the function but that would be a bad design
as far as I can tell. It would still allowed for a user to modify the
library internal state by calling the tst_find_free_loopdev() with the
flag set.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-11 12:51                         ` Cyril Hrubis
@ 2019-07-12  5:25                           ` Yang Xu
  2019-07-17  5:29                             ` Yang Xu
  2019-07-17  6:10                             ` Amir Goldstein
  2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
  1 sibling, 2 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-12  5:25 UTC (permalink / raw)
  To: ltp


> Hi!
>>> This needs more changes than this.
>>>
>>> The problem here is that the function modifies dev_path which is
>>> returned by tst_acquire_device() so if you call this function after
>>> tst_acquire_device() it will rewrite the dev_path which means that the
>>> test would end up with wrong device path in tst_device->dev.
>>>
>>> I guess that the easiest solution would be changing the function to get
>>> buffer parameter which, when non-NULL, is filled with the path.
>>>
>>> I.e. the function prototype would became:
>>>
>>> int tst_find_free_loopdev(char *path, size_t path_len);
>>>
>>> And we would pass the dev_path inside of the tst_device.c and NULL from
>>> the copy_file_range() tests.
>> Hi Cyril
>>
>> This is a good comment. But I doubt why we don't use a set_devpath_flag todistinguish it.
>> Or you have a future plan(in different directory ,/dev,/dev/loop/,/dev/block)?
> Well you can add a flag to the function but that would be a bad design
> as far as I can tell. It would still allowed for a user to modify the
> library internal state by calling the tst_find_free_loopdev() with the
> flag set.
>
Hi  Cyril

Even we use int tst_find_free_loopdev(char *path, size_t path_len), user aslo can modify the internal state.
I don't know how to limit it. Can you give some example code? If we set LTP_DEV in *tst_acquire_device__,
we can pass dev and len to tst_find_free_loopdev(), but if we not set LTP_DEV, what can pass to tst_free_loopdev()?


Thanks
Yang Xu




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-12  5:25                           ` Yang Xu
@ 2019-07-17  5:29                             ` Yang Xu
  2019-07-17  6:10                             ` Amir Goldstein
  1 sibling, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-17  5:29 UTC (permalink / raw)
  To: ltp


>
>> Hi!
>>>> This needs more changes than this.
>>>> The problem here is that the function modifies dev_path which is
>>>> returned by tst_acquire_device() so if you call this function after
>>>> tst_acquire_device() it will rewrite the dev_path which means that the
>>>> test would end up with wrong device path in tst_device->dev.
>>>>
>>>> I guess that the easiest solution would be changing the function to get
>>>> buffer parameter which, when non-NULL, is filled with the path.
>>>> I.e. the function prototype would became:
>>>> int tst_find_free_loopdev(char *path, size_t path_len);
>>>> And we would pass the dev_path inside of the tst_device.c and NULL from
>>>> the copy_file_range() tests.
>>> Hi Cyril
>>> This is a good comment. But I doubt why we don't use a set_devpath_flag todistinguish it.
>>> Or you have a future plan(in different directory ,/dev,/dev/loop/,/dev/block)?
>> Well you can add a flag to the function but that would be a bad design
>> as far as I can tell. It would still allowed for a user to modify the
>> library internal state by calling the tst_find_free_loopdev() with the
>> flag set.
> Hi  Cyril
> Even we use int tst_find_free_loopdev(char *path, size_t path_len), user aslo can modify the internal state.
> I don't know how to limit it. Can you give some example code? If we set LTP_DEV in *tst_acquire_device__,
> we can pass dev and len to tst_find_free_loopdev(), but if we not set LTP_DEV, what can pass to tst_free_loopdev()?
Hi Cyril

ping.  :-)

> Thanks
> Yang Xu
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev()
  2019-07-12  5:25                           ` Yang Xu
  2019-07-17  5:29                             ` Yang Xu
@ 2019-07-17  6:10                             ` Amir Goldstein
  1 sibling, 0 replies; 86+ messages in thread
From: Amir Goldstein @ 2019-07-17  6:10 UTC (permalink / raw)
  To: ltp

On Fri, Jul 12, 2019 at 8:26 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
>
> > Hi!
> >>> This needs more changes than this.
> >>>
> >>> The problem here is that the function modifies dev_path which is
> >>> returned by tst_acquire_device() so if you call this function after
> >>> tst_acquire_device() it will rewrite the dev_path which means that the
> >>> test would end up with wrong device path in tst_device->dev.
> >>>
> >>> I guess that the easiest solution would be changing the function to get
> >>> buffer parameter which, when non-NULL, is filled with the path.
> >>>
> >>> I.e. the function prototype would became:
> >>>
> >>> int tst_find_free_loopdev(char *path, size_t path_len);
> >>>
> >>> And we would pass the dev_path inside of the tst_device.c and NULL from
> >>> the copy_file_range() tests.
> >> Hi Cyril
> >>
> >> This is a good comment. But I doubt why we don't use a set_devpath_flag todistinguish it.
> >> Or you have a future plan(in different directory ,/dev,/dev/loop/,/dev/block)?
> > Well you can add a flag to the function but that would be a bad design
> > as far as I can tell. It would still allowed for a user to modify the
> > library internal state by calling the tst_find_free_loopdev() with the
> > flag set.
> >
> Hi  Cyril
>
> Even we use int tst_find_free_loopdev(char *path, size_t path_len), user aslo can modify the internal state.
> I don't know how to limit it. Can you give some example code? If we set LTP_DEV in *tst_acquire_device__,
> we can pass dev and len to tst_find_free_loopdev(), but if we not set LTP_DEV, what can pass to tst_free_loopdev()?
>
>

I don't understand your concern.
Attached untested patch which implements Cyril's suggestion.

You may call tst_find_free_loopdev(NULL, 0) to get a free minor number
without changing lib internal state.

Thanks,
Amir.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ltp-tst_find_free_loopdev.patch
Type: text/x-patch
Size: 2597 bytes
Desc: not available
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190717/d3591519/attachment-0001.bin>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev()
  2019-07-11 12:51                         ` Cyril Hrubis
  2019-07-12  5:25                           ` Yang Xu
@ 2019-07-17  9:44                           ` Yang Xu
  2019-07-17  9:44                             ` [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
                                               ` (2 more replies)
  1 sibling, 3 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-17  9:44 UTC (permalink / raw)
  To: ltp

Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len),
it passes the dev_path inside of the tst_device.c and NULL from other
tests. It returns the free loopdev minor (and -1 for no free loopdev).
We can call tst_find_free_loopdev(NULL, 0) to get a free minor number
without changing lib internal state.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 doc/test-writing-guidelines.txt | 12 ++++++++++++
 include/tst_device.h            |  5 +++++
 lib/tst_device.c                | 34 +++++++++++++++++----------------
 3 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 4b1e7d25b..c65c707e6 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1045,6 +1045,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
 -------------------------------------------------------------------------------
 #include "tst_test.h"
 
+int tst_find_free_loopdev(const char *path, size_t path_len);
+-------------------------------------------------------------------------------
+
+This function finds a free loopdev and returns the free loopdev minor (-1 for no
+free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+We can call tst_find_free_loopdev(NULL, 0) in tests to get a free minor number
+without changing lib internal state.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
 unsigned long tst_dev_bytes_written(const char *dev);
 -------------------------------------------------------------------------------
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 61902b7e0..42b9fa95b 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -44,6 +44,11 @@ int tst_umount(const char *path);
  */
 int tst_clear_device(const char *dev);
 
+/*
+ * Finds a free loop device for use and returns the free loopdev minor(-1 for no
+ * free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+ */
+int tst_find_free_loopdev(const char *path, size_t path_len);
 /*
  * Reads test block device stat file and returns the bytes written since the
  * last call of this function.
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 65fcc1337..f2516fb08 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -53,22 +53,22 @@ static const char *dev_variants[] = {
 	"/dev/block/loop%i"
 };
 
-static int set_dev_path(int dev)
+static int set_dev_path(int dev, char *path, size_t path_len)
 {
 	unsigned int i;
 	struct stat st;
 
 	for (i = 0; i < ARRAY_SIZE(dev_variants); i++) {
-		snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
+		snprintf(path, path_len, dev_variants[i], dev);
 
-		if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode))
+		if (stat(path, &st) == 0 && S_ISBLK(st.st_mode))
 			return 1;
 	}
 
 	return 0;
 }
 
-static int find_free_loopdev(void)
+int tst_find_free_loopdev(char *path, size_t path_len)
 {
 	int ctl_fd, dev_fd, rc, i;
 	struct loop_info loopinfo;
@@ -80,12 +80,14 @@ static int find_free_loopdev(void)
 		rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
 		close(ctl_fd);
 		if (rc >= 0) {
-			set_dev_path(rc);
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
-			return 0;
+			if (path)
+				set_dev_path(rc, path, path_len);
+			tst_resm(TINFO, "Found free device %d '%s'",
+				rc, path ?: "");
+			return rc;
 		}
 		tst_resm(TINFO, "Couldn't find free loop device");
-		return 1;
+		return -1;
 	}
 
 	switch (errno) {
@@ -104,24 +106,24 @@ static int find_free_loopdev(void)
 	 * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
 	 * LOOP_GET_STATUS ioctl() which fails for free loop devices.
 	 */
-	for (i = 0; i < 256; i++) {
+	for (i = 0; path && i < 256; i++) {
 
-		if (!set_dev_path(i))
+		if (!set_dev_path(i, path, path_len))
 			continue;
 
-		dev_fd = open(dev_path, O_RDONLY);
+		dev_fd = open(path, O_RDONLY);
 
 		if (dev_fd < 0)
 			continue;
 
 		if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) {
-			tst_resm(TINFO, "Device '%s' in use", dev_path);
+			tst_resm(TINFO, "Device '%s' in use", path);
 		} else {
 			if (errno != ENXIO)
 				continue;
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
+			tst_resm(TINFO, "Found free device '%s'", path);
 			close(dev_fd);
-			return 0;
+			return i;
 		}
 
 		close(dev_fd);
@@ -129,7 +131,7 @@ static int find_free_loopdev(void)
 
 	tst_resm(TINFO, "No free devices found");
 
-	return 1;
+	return -1;
 }
 
 static int attach_device(const char *dev, const char *file)
@@ -274,7 +276,7 @@ const char *tst_acquire_device__(unsigned int size)
 		return NULL;
 	}
 
-	if (find_free_loopdev())
+	if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1)
 		return NULL;
 
 	if (attach_device(dev_path, DEV_FILE))
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
@ 2019-07-17  9:44                             ` Yang Xu
  2019-07-29 13:56                               ` Petr Vorel
  2019-07-17  9:44                             ` [LTP] [PATCH v5 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-17 10:14                             ` [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev() Amir Goldstein
  2 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-17  9:44 UTC (permalink / raw)
  To: ltp

Amir has relaxed cross-device constraint since kernel commit 5dae222a5(vfs:
allow copy_file_range to copy across devices), I think we can test it in
copy_file_range01.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../copy_file_range/copy_file_range01.c       | 58 ++++++++++++++-----
 1 file changed, 43 insertions(+), 15 deletions(-)

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 a5bd5e7f7..ec55e5da1 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
@@ -24,7 +24,16 @@
 
 static int page_size;
 static int errcount, numcopies;
-static int fd_in, fd_out;
+static int fd_in, fd_out, cross_sup;
+
+static struct tcase {
+	char    *path;
+	int     flags;
+	char    *message;
+} tcases[] = {
+	{FILE_DEST_PATH,  0, "non cross-device"},
+	{FILE_MNTED_PATH, 1, "cross-device"},
+};
 
 static int check_file_content(const char *fname1, const char *fname2,
 	loff_t *off1, loff_t *off2, size_t len)
@@ -90,7 +99,7 @@ static int check_file_offset(const char *m, int fd, loff_t len,
 	return ret;
 }
 
-static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
+static void test_one(size_t len, loff_t *off_in, loff_t *off_out, char *path)
 {
 	int ret;
 	size_t to_copy = len;
@@ -131,7 +140,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 		to_copy -= TST_RET;
 	} while (to_copy > 0);
 
-	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
+	ret = check_file_content(FILE_SRC_PATH, path,
 		off_in, off_out, len);
 	if (ret) {
 		tst_res(TFAIL, "file contents do not match");
@@ -149,10 +158,10 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 	}
 }
 
-static void open_files(void)
+static void open_files(char *path)
 {
 	fd_in  = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY);
-	fd_out = SAFE_OPEN(FILE_DEST_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+	fd_out = SAFE_OPEN(path, O_CREAT | O_WRONLY | O_TRUNC, 0644);
 }
 
 static void close_files(void)
@@ -163,9 +172,16 @@ static void close_files(void)
 		SAFE_CLOSE(fd_in);
 }
 
-static void copy_file_range_verify(void)
+static void copy_file_range_verify(unsigned int n)
 {
 	int i, j, k;
+	struct tcase *tc = &tcases[n];
+
+	if (tc->flags && !cross_sup) {
+		tst_res(TCONF,
+			"copy_file_range doesn't support cross-device, skip it");
+		return;
+	}
 
 	errcount = numcopies = 0;
 	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
@@ -182,33 +198,41 @@ static void copy_file_range_verify(void)
 	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]);
+				open_files(tc->path);
+				test_one(len_arr[i], off_arr[j], off_arr[k], tc->path);
 				close_files();
 				numcopies++;
 			}
 
 	if (errcount == 0)
 		tst_res(TPASS,
-			"copy_file_range completed all %d copy jobs successfully!",
-			numcopies);
+			"%s copy_file_range completed all %d copy jobs successfully!",
+			tc->message, numcopies);
 	else
-		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
-				errcount, numcopies);
+		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
+			tc->message, errcount, numcopies);
 }
 
 static void setup(void)
 {
-	int i, fd;
+	int i, fd, fd_test;
 
 	syscall_info();
 
 	page_size = getpagesize();
-
+	cross_sup = 1;
 	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, CONTSIZE);
+
+	fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
+	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
+	if (TST_ERR == EXDEV)
+		cross_sup = 0;
+
+	SAFE_CLOSE(fd_test);
+	remove(FILE_MNTED_PATH);
 	SAFE_CLOSE(fd);
 }
 
@@ -220,7 +244,11 @@ static void cleanup(void)
 static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
 	.needs_tmpdir = 1,
-	.test_all = copy_file_range_verify,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.test = copy_file_range_verify,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
  2019-07-17  9:44                             ` [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-17  9:44                             ` Yang Xu
  2019-07-17 10:14                             ` [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev() Amir Goldstein
  2 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-17  9:44 UTC (permalink / raw)
  To: ltp

Since Amir patch[1] for copy_file_range has been merged into upstream
kernel, we should add swapfile, immutable file, bounds tests in ltp.
Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
constraint has been relaxed since[2]). I follow xfstests code[3][4][5].

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
[2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
[3]https://patchwork.kernel.org/patch/10971759/
[4]https://patchwork.kernel.org/patch/10971747/
[5]https://patchwork.kernel.org/patch/10961421/

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 include/lapi/fs.h                             |   7 +
 .../copy_file_range/copy_file_range.h         |  14 +-
 .../copy_file_range/copy_file_range02.c       | 146 +++++++++++++++---
 3 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 42cb4f9b2..5cfdb5450 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -35,4 +35,11 @@
 #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
 #endif
 
+/* Referred form linux kernel include/linux/fs.h */
+#if __WORDSIZE == 64
+ #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
+#else
+ #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
+#endif
+
 #endif
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..aedfda966 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,7 +9,10 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
 #include "lapi/syscalls.h"
+#include "lapi/fs.h"
 
 #define TEST_VARIANTS	2
 
@@ -18,10 +21,19 @@
 #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
+#define FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_BLKDEV    "file_blk"
+#define FILE_CHRDEV    "/dev/null"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_LEN   MAX_LFS_FILESIZE
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..ee45b7636 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     16EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond maximum supported file size ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,78 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
+static int loop_devn;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
+	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
+		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
+		return;
+	}
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,14 +134,27 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (loop_devn >= 0)
+		SAFE_UNLINK(FILE_BLKDEV);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
@@ -92,17 +163,52 @@ static void setup(void)
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
+	/*
+	 * tst_find_free_loopdev() returns the free loopdev minor, we make a
+	 * non-instantiated loop device by using it, avoid overwriting its
+	 * content on used loopdev.
+	 */
+	loop_devn = tst_find_free_loopdev(NULL, 0);
+	if (loop_devn >= 0)
+		SAFE_MKNOD(FILE_BLKDEV, S_IFBLK | 0777, makedev(7, loop_devn));
+
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
 
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+	fd_blkdev = SAFE_OPEN(FILE_BLKDEV, O_RDWR, 0600);
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +219,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev()
  2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
  2019-07-17  9:44                             ` [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
  2019-07-17  9:44                             ` [LTP] [PATCH v5 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-17 10:14                             ` Amir Goldstein
  2019-07-17 10:34                               ` Yang Xu
  2 siblings, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-17 10:14 UTC (permalink / raw)
  To: ltp

On Wed, Jul 17, 2019 at 12:45 PM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len),
> it passes the dev_path inside of the tst_device.c and NULL from other
> tests. It returns the free loopdev minor (and -1 for no free loopdev).
> We can call tst_find_free_loopdev(NULL, 0) to get a free minor number
> without changing lib internal state.
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> ---
>  doc/test-writing-guidelines.txt | 12 ++++++++++++
>  include/tst_device.h            |  5 +++++
>  lib/tst_device.c                | 34 +++++++++++++++++----------------
>  3 files changed, 35 insertions(+), 16 deletions(-)
>
> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
> index 4b1e7d25b..c65c707e6 100644
> --- a/doc/test-writing-guidelines.txt
> +++ b/doc/test-writing-guidelines.txt
> @@ -1045,6 +1045,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>  -------------------------------------------------------------------------------
>  #include "tst_test.h"
>
> +int tst_find_free_loopdev(const char *path, size_t path_len);
> +-------------------------------------------------------------------------------
> +
> +This function finds a free loopdev and returns the free loopdev minor (-1 for no
> +free loopdev). If path is non-NULL, it will be filled with free loopdev path.
> +We can call tst_find_free_loopdev(NULL, 0) in tests to get a free minor number
> +without changing lib internal state.
> +
> +[source,c]
> +-------------------------------------------------------------------------------
> +#include "tst_test.h"
> +
>  unsigned long tst_dev_bytes_written(const char *dev);
>  -------------------------------------------------------------------------------
>
> diff --git a/include/tst_device.h b/include/tst_device.h
> index 61902b7e0..42b9fa95b 100644
> --- a/include/tst_device.h
> +++ b/include/tst_device.h
> @@ -44,6 +44,11 @@ int tst_umount(const char *path);
>   */
>  int tst_clear_device(const char *dev);
>
> +/*
> + * Finds a free loop device for use and returns the free loopdev minor(-1 for no
> + * free loopdev). If path is non-NULL, it will be filled with free loopdev path.
> + */
> +int tst_find_free_loopdev(const char *path, size_t path_len);
>  /*
>   * Reads test block device stat file and returns the bytes written since the
>   * last call of this function.
> diff --git a/lib/tst_device.c b/lib/tst_device.c
> index 65fcc1337..f2516fb08 100644
> --- a/lib/tst_device.c
> +++ b/lib/tst_device.c
> @@ -53,22 +53,22 @@ static const char *dev_variants[] = {
>         "/dev/block/loop%i"
>  };
>
> -static int set_dev_path(int dev)
> +static int set_dev_path(int dev, char *path, size_t path_len)
>  {
>         unsigned int i;
>         struct stat st;
>
>         for (i = 0; i < ARRAY_SIZE(dev_variants); i++) {
> -               snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
> +               snprintf(path, path_len, dev_variants[i], dev);
>
> -               if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode))
> +               if (stat(path, &st) == 0 && S_ISBLK(st.st_mode))
>                         return 1;
>         }
>
>         return 0;
>  }
>
> -static int find_free_loopdev(void)
> +int tst_find_free_loopdev(char *path, size_t path_len)

Another option is to leave this function internal and export a wrapper
for the exact needed functionality:

/* Just find a free minor number */
int tst_find_free_loopdev(void)
{
        return find_free_loopdev(NULL, 0);
}

I don't mind wither way.

>  {
>         int ctl_fd, dev_fd, rc, i;
>         struct loop_info loopinfo;
> @@ -80,12 +80,14 @@ static int find_free_loopdev(void)
>                 rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
>                 close(ctl_fd);
>                 if (rc >= 0) {
> -                       set_dev_path(rc);
> -                       tst_resm(TINFO, "Found free device '%s'", dev_path);
> -                       return 0;
> +                       if (path)
> +                               set_dev_path(rc, path, path_len);
> +                       tst_resm(TINFO, "Found free device %d '%s'",
> +                               rc, path ?: "");
> +                       return rc;
>                 }
>                 tst_resm(TINFO, "Couldn't find free loop device");
> -               return 1;
> +               return -1;
>         }
>
>         switch (errno) {
> @@ -104,24 +106,24 @@ static int find_free_loopdev(void)
>          * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
>          * LOOP_GET_STATUS ioctl() which fails for free loop devices.
>          */
> -       for (i = 0; i < 256; i++) {
> +       for (i = 0; path && i < 256; i++) {
>
> -               if (!set_dev_path(i))
> +               if (!set_dev_path(i, path, path_len))
>                         continue;
>
> -               dev_fd = open(dev_path, O_RDONLY);
> +               dev_fd = open(path, O_RDONLY);
>
>                 if (dev_fd < 0)
>                         continue;
>
>                 if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) {
> -                       tst_resm(TINFO, "Device '%s' in use", dev_path);
> +                       tst_resm(TINFO, "Device '%s' in use", path);
>                 } else {
>                         if (errno != ENXIO)
>                                 continue;
> -                       tst_resm(TINFO, "Found free device '%s'", dev_path);
> +                       tst_resm(TINFO, "Found free device '%s'", path);
>                         close(dev_fd);
> -                       return 0;
> +                       return i;
>                 }
>
>                 close(dev_fd);
> @@ -129,7 +131,7 @@ static int find_free_loopdev(void)
>
>         tst_resm(TINFO, "No free devices found");
>
> -       return 1;
> +       return -1;
>  }
>
>  static int attach_device(const char *dev, const char *file)
> @@ -274,7 +276,7 @@ const char *tst_acquire_device__(unsigned int size)
>                 return NULL;
>         }
>
> -       if (find_free_loopdev())
> +       if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1)
>                 return NULL;
>
>         if (attach_device(dev_path, DEV_FILE))
> --
> 2.18.1
>
>
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev()
  2019-07-17 10:14                             ` [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev() Amir Goldstein
@ 2019-07-17 10:34                               ` Yang Xu
  2019-07-17 10:54                                 ` Cyril Hrubis
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-17 10:34 UTC (permalink / raw)
  To: ltp


> On Wed, Jul 17, 2019 at 12:45 PM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len),
>> it passes the dev_path inside of the tst_device.c and NULL from other
>> tests. It returns the free loopdev minor (and -1 for no free loopdev).
>> We can call tst_find_free_loopdev(NULL, 0) to get a free minor number
>> without changing lib internal state.
>>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> Reviewed-by: Amir Goldstein<amir73il@gmail.com>
>> ---
>>   doc/test-writing-guidelines.txt | 12 ++++++++++++
>>   include/tst_device.h            |  5 +++++
>>   lib/tst_device.c                | 34 +++++++++++++++++----------------
>>   3 files changed, 35 insertions(+), 16 deletions(-)
>>
>> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
>> index 4b1e7d25b..c65c707e6 100644
>> --- a/doc/test-writing-guidelines.txt
>> +++ b/doc/test-writing-guidelines.txt
>> @@ -1045,6 +1045,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>>   -------------------------------------------------------------------------------
>>   #include "tst_test.h"
>>
>> +int tst_find_free_loopdev(const char *path, size_t path_len);
>> +-------------------------------------------------------------------------------
>> +
>> +This function finds a free loopdev and returns the free loopdev minor (-1 for no
>> +free loopdev). If path is non-NULL, it will be filled with free loopdev path.
>> +We can call tst_find_free_loopdev(NULL, 0) in tests to get a free minor number
>> +without changing lib internal state.
>> +
>> +[source,c]
>> +-------------------------------------------------------------------------------
>> +#include "tst_test.h"
>> +
>>   unsigned long tst_dev_bytes_written(const char *dev);
>>   -------------------------------------------------------------------------------
>>
>> diff --git a/include/tst_device.h b/include/tst_device.h
>> index 61902b7e0..42b9fa95b 100644
>> --- a/include/tst_device.h
>> +++ b/include/tst_device.h
>> @@ -44,6 +44,11 @@ int tst_umount(const char *path);
>>    */
>>   int tst_clear_device(const char *dev);
>>
>> +/*
>> + * Finds a free loop device for use and returns the free loopdev minor(-1 for no
>> + * free loopdev). If path is non-NULL, it will be filled with free loopdev path.
>> + */
>> +int tst_find_free_loopdev(const char *path, size_t path_len);
>>   /*
>>    * Reads test block device stat file and returns the bytes written since the
>>    * last call of this function.
>> diff --git a/lib/tst_device.c b/lib/tst_device.c
>> index 65fcc1337..f2516fb08 100644
>> --- a/lib/tst_device.c
>> +++ b/lib/tst_device.c
>> @@ -53,22 +53,22 @@ static const char *dev_variants[] = {
>>          "/dev/block/loop%i"
>>   };
>>
>> -static int set_dev_path(int dev)
>> +static int set_dev_path(int dev, char *path, size_t path_len)
>>   {
>>          unsigned int i;
>>          struct stat st;
>>
>>          for (i = 0; i<  ARRAY_SIZE(dev_variants); i++) {
>> -               snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
>> +               snprintf(path, path_len, dev_variants[i], dev);
>>
>> -               if (stat(dev_path,&st) == 0&&  S_ISBLK(st.st_mode))
>> +               if (stat(path,&st) == 0&&  S_ISBLK(st.st_mode))
>>                          return 1;
>>          }
>>
>>          return 0;
>>   }
>>
>> -static int find_free_loopdev(void)
>> +int tst_find_free_loopdev(char *path, size_t path_len)
> Another option is to leave this function internal and export a wrapper
> for the exact needed functionality:
>
> /* Just find a free minor number */
> int tst_find_free_loopdev(void)
> {
>          return find_free_loopdev(NULL, 0);
> }
>
> I don't mind wither way.
Hi Amir

The second way looks better for me.  But I also want to hear the idea of cyril.

>>   {
>>          int ctl_fd, dev_fd, rc, i;
>>          struct loop_info loopinfo;
>> @@ -80,12 +80,14 @@ static int find_free_loopdev(void)
>>                  rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
>>                  close(ctl_fd);
>>                  if (rc>= 0) {
>> -                       set_dev_path(rc);
>> -                       tst_resm(TINFO, "Found free device '%s'", dev_path);
>> -                       return 0;
>> +                       if (path)
>> +                               set_dev_path(rc, path, path_len);
>> +                       tst_resm(TINFO, "Found free device %d '%s'",
>> +                               rc, path ?: "");
>> +                       return rc;
>>                  }
>>                  tst_resm(TINFO, "Couldn't find free loop device");
>> -               return 1;
>> +               return -1;
>>          }
>>
>>          switch (errno) {
>> @@ -104,24 +106,24 @@ static int find_free_loopdev(void)
>>           * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
>>           * LOOP_GET_STATUS ioctl() which fails for free loop devices.
>>           */
>> -       for (i = 0; i<  256; i++) {
>> +       for (i = 0; path&&  i<  256; i++) {
>>
>> -               if (!set_dev_path(i))
>> +               if (!set_dev_path(i, path, path_len))
>>                          continue;
>>
>> -               dev_fd = open(dev_path, O_RDONLY);
>> +               dev_fd = open(path, O_RDONLY);
>>
>>                  if (dev_fd<  0)
>>                          continue;
>>
>>                  if (ioctl(dev_fd, LOOP_GET_STATUS,&loopinfo) == 0) {
>> -                       tst_resm(TINFO, "Device '%s' in use", dev_path);
>> +                       tst_resm(TINFO, "Device '%s' in use", path);
>>                  } else {
>>                          if (errno != ENXIO)
>>                                  continue;
>> -                       tst_resm(TINFO, "Found free device '%s'", dev_path);
>> +                       tst_resm(TINFO, "Found free device '%s'", path);
>>                          close(dev_fd);
>> -                       return 0;
>> +                       return i;
>>                  }
>>
>>                  close(dev_fd);
>> @@ -129,7 +131,7 @@ static int find_free_loopdev(void)
>>
>>          tst_resm(TINFO, "No free devices found");
>>
>> -       return 1;
>> +       return -1;
>>   }
>>
>>   static int attach_device(const char *dev, const char *file)
>> @@ -274,7 +276,7 @@ const char *tst_acquire_device__(unsigned int size)
>>                  return NULL;
>>          }
>>
>> -       if (find_free_loopdev())
>> +       if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1)
>>                  return NULL;
>>
>>          if (attach_device(dev_path, DEV_FILE))
>> --
>> 2.18.1
>>
>>
>>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev()
  2019-07-17 10:34                               ` Yang Xu
@ 2019-07-17 10:54                                 ` Cyril Hrubis
  2019-07-18  7:30                                   ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-17 10:54 UTC (permalink / raw)
  To: ltp

Hi!
> > Another option is to leave this function internal and export a wrapper
> > for the exact needed functionality:
> >
> > /* Just find a free minor number */
> > int tst_find_free_loopdev(void)
> > {
> >          return find_free_loopdev(NULL, 0);
> > }
> >
> > I don't mind wither way.
> Hi Amir
> 
> The second way looks better for me.  But I also want to hear the idea of cyril.

Well I wanted to keep the path exposed to user in a case that there
would be a test that would need more than one device. But it's not like
we cannot change the API later when it's actually needed.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev()
  2019-07-17 10:54                                 ` Cyril Hrubis
@ 2019-07-18  7:30                                   ` Yang Xu
  2019-07-25  5:01                                     ` [LTP] [PATCH v6 " Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-18  7:30 UTC (permalink / raw)
  To: ltp

> Hi!
>>> Another option is to leave this function internal and export a wrapper
>>> for the exact needed functionality:
>>>
>>> /* Just find a free minor number */
>>> int tst_find_free_loopdev(void)
>>> {
>>>           return find_free_loopdev(NULL, 0);
>>> }
>>>
>>> I don't mind wither way.
>> Hi Amir
>>
>> The second way looks better for me.  But I also want to hear the idea of cyril.
> Well I wanted to keep the path exposed to user in a case that there
> would be a test that would need more than one device. But it's not like
> we cannot change the API later when it's actually needed.
>
Hi Cyril


Ok. I will use the first way to expose the path. Also on my copy_file_range02, I will directly use
path filled with this api because it doesn't change libary state.

If you think this pathset is no problem, I will send v6 patch.


Thanks
Yang Xu



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190718/e647c11e/attachment-0001.htm>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev()
  2019-07-18  7:30                                   ` Yang Xu
@ 2019-07-25  5:01                                     ` Yang Xu
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
                                                         ` (2 more replies)
  0 siblings, 3 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-25  5:01 UTC (permalink / raw)
  To: ltp

Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len),
tst_acquire_device() passes the dev_path and path_len inside of
the tst_device.c. It returns the free loopdev minor (and -1 for no
free loopdev). If path is non-NULL, it will be filled with free
loopdev path. We also can call tst_find_free_loopdev(NULL, 0) to
make a customized loopdev by using mkdnod.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
-------
v5->v6:
     correct some message
---
 doc/test-writing-guidelines.txt | 12 ++++++++++++
 include/tst_device.h            |  6 ++++++
 lib/tst_device.c                | 34 +++++++++++++++++----------------
 3 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index e59d72065..d21fbf76a 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1053,6 +1053,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
 -------------------------------------------------------------------------------
 #include "tst_test.h"
 
+int tst_find_free_loopdev(const char *path, size_t path_len);
+-------------------------------------------------------------------------------
+
+This function finds a free loopdev and returns the free loopdev minor (-1 for no
+free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+If you want to use a customized loop device, we can call tst_find_free_loopdev
+(NULL, 0) in tests to get a free minor number. Then mknod.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
 unsigned long tst_dev_bytes_written(const char *dev);
 -------------------------------------------------------------------------------
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 61902b7e0..f0ddc3e93 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -44,6 +44,12 @@ int tst_umount(const char *path);
  */
 int tst_clear_device(const char *dev);
 
+/*
+ * Finds a free loop device for use and returns the free loopdev minor(-1 for no
+ * free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+ *
+ */
+int tst_find_free_loopdev(const char *path, size_t path_len);
 /*
  * Reads test block device stat file and returns the bytes written since the
  * last call of this function.
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 65fcc1337..f2516fb08 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -53,22 +53,22 @@ static const char *dev_variants[] = {
 	"/dev/block/loop%i"
 };
 
-static int set_dev_path(int dev)
+static int set_dev_path(int dev, char *path, size_t path_len)
 {
 	unsigned int i;
 	struct stat st;
 
 	for (i = 0; i < ARRAY_SIZE(dev_variants); i++) {
-		snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
+		snprintf(path, path_len, dev_variants[i], dev);
 
-		if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode))
+		if (stat(path, &st) == 0 && S_ISBLK(st.st_mode))
 			return 1;
 	}
 
 	return 0;
 }
 
-static int find_free_loopdev(void)
+int tst_find_free_loopdev(char *path, size_t path_len)
 {
 	int ctl_fd, dev_fd, rc, i;
 	struct loop_info loopinfo;
@@ -80,12 +80,14 @@ static int find_free_loopdev(void)
 		rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
 		close(ctl_fd);
 		if (rc >= 0) {
-			set_dev_path(rc);
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
-			return 0;
+			if (path)
+				set_dev_path(rc, path, path_len);
+			tst_resm(TINFO, "Found free device %d '%s'",
+				rc, path ?: "");
+			return rc;
 		}
 		tst_resm(TINFO, "Couldn't find free loop device");
-		return 1;
+		return -1;
 	}
 
 	switch (errno) {
@@ -104,24 +106,24 @@ static int find_free_loopdev(void)
 	 * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
 	 * LOOP_GET_STATUS ioctl() which fails for free loop devices.
 	 */
-	for (i = 0; i < 256; i++) {
+	for (i = 0; path && i < 256; i++) {
 
-		if (!set_dev_path(i))
+		if (!set_dev_path(i, path, path_len))
 			continue;
 
-		dev_fd = open(dev_path, O_RDONLY);
+		dev_fd = open(path, O_RDONLY);
 
 		if (dev_fd < 0)
 			continue;
 
 		if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) {
-			tst_resm(TINFO, "Device '%s' in use", dev_path);
+			tst_resm(TINFO, "Device '%s' in use", path);
 		} else {
 			if (errno != ENXIO)
 				continue;
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
+			tst_resm(TINFO, "Found free device '%s'", path);
 			close(dev_fd);
-			return 0;
+			return i;
 		}
 
 		close(dev_fd);
@@ -129,7 +131,7 @@ static int find_free_loopdev(void)
 
 	tst_resm(TINFO, "No free devices found");
 
-	return 1;
+	return -1;
 }
 
 static int attach_device(const char *dev, const char *file)
@@ -274,7 +276,7 @@ const char *tst_acquire_device__(unsigned int size)
 		return NULL;
 	}
 
-	if (find_free_loopdev())
+	if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1)
 		return NULL;
 
 	if (attach_device(dev_path, DEV_FILE))
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-25  5:01                                     ` [LTP] [PATCH v6 " Yang Xu
@ 2019-07-25  5:01                                       ` Yang Xu
  2019-07-29 14:00                                         ` Petr Vorel
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-29 13:01                                       ` [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev() Cyril Hrubis
  2 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-25  5:01 UTC (permalink / raw)
  To: ltp

Amir has relaxed cross-device constraint since commit[1], I think we can test it in
copy_file_range01.

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../copy_file_range/copy_file_range01.c       | 58 ++++++++++++++-----
 1 file changed, 43 insertions(+), 15 deletions(-)

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 a5bd5e7f7..ec55e5da1 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
@@ -24,7 +24,16 @@
 
 static int page_size;
 static int errcount, numcopies;
-static int fd_in, fd_out;
+static int fd_in, fd_out, cross_sup;
+
+static struct tcase {
+	char    *path;
+	int     flags;
+	char    *message;
+} tcases[] = {
+	{FILE_DEST_PATH,  0, "non cross-device"},
+	{FILE_MNTED_PATH, 1, "cross-device"},
+};
 
 static int check_file_content(const char *fname1, const char *fname2,
 	loff_t *off1, loff_t *off2, size_t len)
@@ -90,7 +99,7 @@ static int check_file_offset(const char *m, int fd, loff_t len,
 	return ret;
 }
 
-static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
+static void test_one(size_t len, loff_t *off_in, loff_t *off_out, char *path)
 {
 	int ret;
 	size_t to_copy = len;
@@ -131,7 +140,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 		to_copy -= TST_RET;
 	} while (to_copy > 0);
 
-	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
+	ret = check_file_content(FILE_SRC_PATH, path,
 		off_in, off_out, len);
 	if (ret) {
 		tst_res(TFAIL, "file contents do not match");
@@ -149,10 +158,10 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 	}
 }
 
-static void open_files(void)
+static void open_files(char *path)
 {
 	fd_in  = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY);
-	fd_out = SAFE_OPEN(FILE_DEST_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+	fd_out = SAFE_OPEN(path, O_CREAT | O_WRONLY | O_TRUNC, 0644);
 }
 
 static void close_files(void)
@@ -163,9 +172,16 @@ static void close_files(void)
 		SAFE_CLOSE(fd_in);
 }
 
-static void copy_file_range_verify(void)
+static void copy_file_range_verify(unsigned int n)
 {
 	int i, j, k;
+	struct tcase *tc = &tcases[n];
+
+	if (tc->flags && !cross_sup) {
+		tst_res(TCONF,
+			"copy_file_range doesn't support cross-device, skip it");
+		return;
+	}
 
 	errcount = numcopies = 0;
 	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
@@ -182,33 +198,41 @@ static void copy_file_range_verify(void)
 	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]);
+				open_files(tc->path);
+				test_one(len_arr[i], off_arr[j], off_arr[k], tc->path);
 				close_files();
 				numcopies++;
 			}
 
 	if (errcount == 0)
 		tst_res(TPASS,
-			"copy_file_range completed all %d copy jobs successfully!",
-			numcopies);
+			"%s copy_file_range completed all %d copy jobs successfully!",
+			tc->message, numcopies);
 	else
-		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
-				errcount, numcopies);
+		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
+			tc->message, errcount, numcopies);
 }
 
 static void setup(void)
 {
-	int i, fd;
+	int i, fd, fd_test;
 
 	syscall_info();
 
 	page_size = getpagesize();
-
+	cross_sup = 1;
 	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, CONTSIZE);
+
+	fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
+	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
+	if (TST_ERR == EXDEV)
+		cross_sup = 0;
+
+	SAFE_CLOSE(fd_test);
+	remove(FILE_MNTED_PATH);
 	SAFE_CLOSE(fd);
 }
 
@@ -220,7 +244,11 @@ static void cleanup(void)
 static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
 	.needs_tmpdir = 1,
-	.test_all = copy_file_range_verify,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.test = copy_file_range_verify,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  5:01                                     ` [LTP] [PATCH v6 " Yang Xu
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-25  5:01                                       ` Yang Xu
  2019-07-25  5:24                                         ` Amir Goldstein
  2019-07-30 13:26                                         ` Petr Vorel
  2019-07-29 13:01                                       ` [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev() Cyril Hrubis
  2 siblings, 2 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-25  5:01 UTC (permalink / raw)
  To: ltp

Since Amir patch[1] for copy_file_range has been merged into upstream
kernel, we should add swapfile, immutable file, bounds tests in ltp.
Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
constraint has been relaxed since[2]). I follow xfstests code[3].

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
[2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
[3]https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/553{554,564,565}

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>

----
v5->v6:
   1)directly use the tst_find_free_loopdev filling dev_path
   2)use TST_ABI64 instead of __WORDSIZE == 64
---
 include/lapi/fs.h                             |   8 +
 .../copy_file_range/copy_file_range.h         |  13 +-
 .../copy_file_range/copy_file_range02.c       | 145 +++++++++++++++---
 3 files changed, 145 insertions(+), 21 deletions(-)

diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 42cb4f9b2..708cb8902 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -7,6 +7,7 @@
 #ifdef HAVE_LINUX_FS_H
 # include <linux/fs.h>
 #endif
+# include "lapi/abisize.h"
 
 #ifndef LAPI_FS_H
 #define LAPI_FS_H
@@ -35,4 +36,11 @@
 #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
 #endif
 
+/* Referred form linux kernel include/linux/fs.h */
+#ifdef TST_ABI64
+ #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
+#else
+ #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
+#endif
+
 #endif
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..c7f423e45 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,7 +9,10 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
 #include "lapi/syscalls.h"
+#include "lapi/fs.h"
 
 #define TEST_VARIANTS	2
 
@@ -18,10 +21,18 @@
 #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
+#define FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_CHRDEV    "/dev/null"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_LEN   MAX_LFS_FILESIZE
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..36976156e 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     16EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond maximum supported file size ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,78 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
+static int loop_devn;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
+	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
+		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
+		return;
+	}
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,33 +134,80 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
 {
 	syscall_info();
+	char dev_path[1024];
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
+	/*
+	 * call tst_find_free_loopdev(), avoid overwriting its
+	 * content on used loopdev.
+	 */
+	loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
 
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+
+	if (loop_devn == -1)
+		fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
+
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +218,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-25  5:24                                         ` Amir Goldstein
  2019-07-25  5:44                                           ` Yang Xu
  2019-07-30 13:26                                         ` Petr Vorel
  1 sibling, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-25  5:24 UTC (permalink / raw)
  To: ltp

On Thu, Jul 25, 2019 at 8:02 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> Since Amir patch[1] for copy_file_range has been merged into upstream
> kernel, we should add swapfile, immutable file, bounds tests in ltp.
> Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
> constraint has been relaxed since[2]). I follow xfstests code[3].
>
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
> [3]https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/553{554,564,565}
>
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
>
> ----
> v5->v6:
>    1)directly use the tst_find_free_loopdev filling dev_path
>    2)use TST_ABI64 instead of __WORDSIZE == 64
> ---
>  include/lapi/fs.h                             |   8 +
>  .../copy_file_range/copy_file_range.h         |  13 +-
>  .../copy_file_range/copy_file_range02.c       | 145 +++++++++++++++---
>  3 files changed, 145 insertions(+), 21 deletions(-)
>
> diff --git a/include/lapi/fs.h b/include/lapi/fs.h
> index 42cb4f9b2..708cb8902 100644
> --- a/include/lapi/fs.h
> +++ b/include/lapi/fs.h
> @@ -7,6 +7,7 @@
>  #ifdef HAVE_LINUX_FS_H
>  # include <linux/fs.h>
>  #endif
> +# include "lapi/abisize.h"
>
>  #ifndef LAPI_FS_H
>  #define LAPI_FS_H
> @@ -35,4 +36,11 @@
>  #define FS_NODUMP_FL      0x00000040 /* do not dump file */
>  #endif
>
> +/* Referred form linux kernel include/linux/fs.h */
> +#ifdef TST_ABI64
> + #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
> +#else
> + #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
> +#endif
> +
>  #endif
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> index b6d132978..c7f423e45 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -9,7 +9,10 @@
>
>  #include <stdbool.h>
>  #include <unistd.h>
> +#include <sys/sysmacros.h>
> +#include <limits.h>
>  #include "lapi/syscalls.h"
> +#include "lapi/fs.h"
>
>  #define TEST_VARIANTS  2
>
> @@ -18,10 +21,18 @@
>  #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
> +#define FILE_IMMUTABLE_PATH "file_immutable"
> +#define FILE_SWAP_PATH "file_swap"
> +#define FILE_CHRDEV    "/dev/null"
> +#define FILE_FIFO      "file_fifo"
> +#define FILE_COPY_PATH  "file_copy"
>
>  #define CONTENT                "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>  #define CONTSIZE       (sizeof(CONTENT) - 1)
> +#define MAX_LEN   MAX_LFS_FILESIZE
> +#define MIN_OFF   65537
> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
>
>  static void syscall_info(void)
>  {
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 07c0207c2..36976156e 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -10,15 +10,25 @@
>   *
>   * 1) Try to copy contents to file open as readonly
>   *    -> EBADF
> - * 2) Try to copy contents to file on different mounted
> - *    filesystem -> EXDEV
> - * 3) Try to copy contents to directory -> EISDIR
> - * 4) Try to copy contents to a file opened with the
> + * 2) Try to copy contents to directory -> EISDIR
> + * 3) Try to copy contents to a file opened with the
>   *    O_APPEND flag -> EBADF
> - * 5) Try to copy contents to closed filedescriptor
> + * 4) Try to copy contents to closed filedescriptor
>   *    -> EBADF
> - * 6) Try to copy contents with invalid 'flags' value
> + * 5) Try to copy contents with invalid 'flags' value
>   *    -> EINVAL
> + * 6) Try to copy contents to a file chattred with +i
> + *    flag -> EPERM
> + * 7) Try to copy contents to a swapfile ->ETXTBSY
> + * 8) Try to copy contents to the samefile with overlapping
> + *    ->EINVAL
> + * 9) Try to copy contents to a blkdev ->EINVAL
> + * 10) Try to copy contents to a chardev ->EINVAL
> + * 11) Try to copy contents to a FIFO ->EINVAL
> + * 12) Try to copy contents to a file with length beyond
> + *     16EiB wraps around 0 -> EOVERFLOW
> + * 13) Try to copy contents to a file with target file range
> + *     beyond maximum supported file size ->EFBIG
>   */
>
>  #define _GNU_SOURCE
> @@ -29,30 +39,78 @@
>  static int fd_src;
>  static int fd_dest;
>  static int fd_rdonly;
> -static int fd_mnted;
>  static int fd_dir;
>  static int fd_closed;
>  static int fd_append;
> +static int fd_immutable;
> +static int fd_swapfile;
> +static int fd_dup;
> +static int fd_blkdev;
> +static int fd_chrdev;
> +static int fd_fifo;
> +static int fd_copy;
> +
> +static int chattr_i_nsup;
> +static int swap_nsup;
> +static int loop_devn;
>
>  static struct tcase {
>         int     *copy_to_fd;
>         int     flags;
>         int     exp_err;
> +       loff_t  dst;
> +       loff_t     len;
>  } tcases[] = {
> -       {&fd_rdonly,    0,      EBADF},
> -       {&fd_mnted,     0,      EXDEV},
> -       {&fd_dir,       0,      EISDIR},
> -       {&fd_append,    0,      EBADF},
> -       {&fd_closed,    0,      EBADF},
> -       {&fd_dest,      -1,     EINVAL},
> +       {&fd_rdonly,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dir,       0,   EISDIR,     0,     CONTSIZE},
> +       {&fd_append,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_closed,    0,   EBADF,      0,     CONTSIZE},
> +       {&fd_dest,      -1,  EINVAL,     0,     CONTSIZE},
> +       {&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
> +       {&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
> +       {&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
> +       {&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
> +       {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
> +       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
>
> +static int run_command(char *command, char *option, char *file)
> +{
> +       const char *const cmd[] = {command, option, file, NULL};
> +       int ret;
> +
> +       ret = tst_run_cmd(cmd, NULL, NULL, 1);
> +       switch (ret) {
> +       case 0:
> +       return 0;
> +       case 255:
> +               tst_res(TCONF, "%s binary not installed", command);
> +       return 1;
> +       default:
> +               tst_res(TCONF, "%s exited with %i", command, ret);
> +       return 2;
> +       }
> +}
> +
>  static void verify_copy_file_range(unsigned int n)
>  {
>         struct tcase *tc = &tcases[n];
> -
> +       if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
> +               tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
> +               return;
> +       }
> +       if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
> +               tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
> +               return;
> +       }
> +       if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
> +               tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
> +               return;
> +       }
>         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
> -                               0, CONTSIZE, tc->flags));
> +                               &tc->dst, tc->len, tc->flags));
>
>         if (TST_RET == -1) {
>                 if (tc->exp_err == TST_ERR) {
> @@ -76,33 +134,80 @@ static void cleanup(void)
>                 SAFE_CLOSE(fd_append);
>         if (fd_dir > 0)
>                 SAFE_CLOSE(fd_dir);
> -       if (fd_mnted > 0)
> -               SAFE_CLOSE(fd_mnted);
>         if (fd_rdonly > 0)
>                 SAFE_CLOSE(fd_rdonly);
>         if (fd_dest > 0)
>                 SAFE_CLOSE(fd_dest);
>         if (fd_src > 0)
>                 SAFE_CLOSE(fd_src);
> +       if (fd_immutable > 0) {
> +               run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
> +               SAFE_CLOSE(fd_immutable);
> +       }
> +       if (fd_swapfile > 0) {
> +               run_command("swapoff", FILE_SWAP_PATH, NULL);
> +               SAFE_CLOSE(fd_swapfile);
> +       }
> +       if (fd_dup > 0)
> +               SAFE_CLOSE(fd_dup);
> +       if (fd_copy > 0)
> +               SAFE_CLOSE(fd_copy);
> +       SAFE_UNLINK(FILE_FIFO);
>  }
>
>  static void setup(void)
>  {
>         syscall_info();
> +       char dev_path[1024];

Why? What is the point of filling this string if you're not going to
use it. That's exactly what tst_find_free_loopdev(NULL, 0) is for.
I don't think you understood Cyril's comment about the API
correctly.
He meant he rather keep the *option* in the API to fill out the
suggested loopdev file name. Not that you *have* to fill it.

Thanks,
Amir.



>
>         if (access(FILE_DIR_PATH, F_OK) == -1)
>                 SAFE_MKDIR(FILE_DIR_PATH, 0777);
> +       /*
> +        * call tst_find_free_loopdev(), avoid overwriting its
> +        * content on used loopdev.
> +        */
> +       loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
> +
> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
>
>         fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>         fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>         fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>         fd_closed = -1;
>         fd_append = SAFE_OPEN(FILE_DEST_PATH,
>                         O_RDWR | O_CREAT | O_APPEND, 0664);
> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
> +
> +       if (loop_devn == -1)
> +               fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
> +
> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
> +
> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
> +       close(fd_src);
> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
> +
> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
> +       chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> +
> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
> +               tst_res(TCONF, "Insufficient disk space to create swap file");
> +               swap_nsup = 3;
> +               return;
> +       }
> +
> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
> +               tst_res(TCONF, "Failed to create swapfile");
> +               swap_nsup = 4;
> +               return;
> +       }
>
> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
> +       swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
> +       swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
>  }
>
>  static struct tst_test test = {
> @@ -113,6 +218,6 @@ static struct tst_test test = {
>         .needs_root = 1,
>         .mount_device = 1,
>         .mntpoint = MNTPOINT,
> -       .dev_fs_type = "ext4",
> +       .all_filesystems = 1,
>         .test_variants = TEST_VARIANTS,
>  };
> --
> 2.18.1
>
>
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  5:24                                         ` Amir Goldstein
@ 2019-07-25  5:44                                           ` Yang Xu
  2019-07-25  8:08                                             ` Amir Goldstein
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-25  5:44 UTC (permalink / raw)
  To: ltp

on 2019/07/25 13:24, Amir Goldstein wrote:

> On Thu, Jul 25, 2019 at 8:02 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>>
>>
>>   static void setup(void)
>>   {
>>          syscall_info();
>> +       char dev_path[1024];
> Why? What is the point of filling this string if you're not going to
> use it. That's exactly what tst_find_free_loopdev(NULL, 0) is for.
> I don't think you understood Cyril's comment about the API
> correctly.
> He meant he rather keep the *option* in the API to fill out the
> suggested loopdev file name. Not that you *have* to fill it.
>
> Thanks,
> Amir.
>
Hi Amir

  I think you don't see the whole patch.

  I use this dev_path as below:

  fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);

on v5 patch, I use  tst_find_free_loopdev(NULL, 0) and create a customized loop dev named "file_block" by mknod .

But why we don't use a path directly filled by tst_find_free_loopdev(dev_path, len)? It will not change lib internal state or overwirte data.

I only use a standard loop device as same as char device use "/dev/null".

Thanks
Yang Xu


>
>>          if (access(FILE_DIR_PATH, F_OK) == -1)
>>                  SAFE_MKDIR(FILE_DIR_PATH, 0777);
>> +       /*
>> +        * call tst_find_free_loopdev(), avoid overwriting its
>> +        * content on used loopdev.
>> +        */
>> +       loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
>> +
>> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
>>
>>          fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
>> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>>          fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>>          fd_closed = -1;
>>          fd_append = SAFE_OPEN(FILE_DEST_PATH,
>>                          O_RDWR | O_CREAT | O_APPEND, 0664);
>> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
>> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
>> +
>> +       if (loop_devn == -1)
>> +               fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
>> +
       I use the dev_path string.

>> +       fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
>> +       fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
>> +
>> +       SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
>> +       close(fd_src);
>> +       fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
>> +       fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
>> +
>> +       fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
>> +       chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
>> +
>> +       if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
>> +               tst_res(TCONF, "Insufficient disk space to create swap file");
>> +               swap_nsup = 3;
>> +               return;
>> +       }
>> +
>> +       if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
>> +               tst_res(TCONF, "Failed to create swapfile");
>> +               swap_nsup = 4;
>> +               return;
>> +       }
>>
>> -       SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
>> +       swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
>> +       swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
>>   }
>>
>>   static struct tst_test test = {
>> @@ -113,6 +218,6 @@ static struct tst_test test = {
>>          .needs_root = 1,
>>          .mount_device = 1,
>>          .mntpoint = MNTPOINT,
>> -       .dev_fs_type = "ext4",
>> +       .all_filesystems = 1,
>>          .test_variants = TEST_VARIANTS,
>>   };
>> --
>> 2.18.1
>>
>>
>>
>>
>> --
>> Mailing list info: https://lists.linux.it/listinfo/ltp
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  5:44                                           ` Yang Xu
@ 2019-07-25  8:08                                             ` Amir Goldstein
  2019-07-25 10:13                                               ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Amir Goldstein @ 2019-07-25  8:08 UTC (permalink / raw)
  To: ltp

On Thu, Jul 25, 2019 at 8:44 AM Yang Xu <xuyang2018.jy@cn.fujitsu.com> wrote:
>
> on 2019/07/25 13:24, Amir Goldstein wrote:
>
> > On Thu, Jul 25, 2019 at 8:02 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
> >>
> >>
> >>   static void setup(void)
> >>   {
> >>          syscall_info();
> >> +       char dev_path[1024];
> > Why? What is the point of filling this string if you're not going to
> > use it. That's exactly what tst_find_free_loopdev(NULL, 0) is for.
> > I don't think you understood Cyril's comment about the API
> > correctly.
> > He meant he rather keep the *option* in the API to fill out the
> > suggested loopdev file name. Not that you *have* to fill it.
> >
> > Thanks,
> > Amir.
> >
> Hi Amir
>
>   I think you don't see the whole patch.
>
>   I use this dev_path as below:
>
>   fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
>
> on v5 patch, I use  tst_find_free_loopdev(NULL, 0) and create a customized loop dev named "file_block" by mknod .
>
> But why we don't use a path directly filled by tst_find_free_loopdev(dev_path, len)? It will not change lib internal state or overwirte data.
>
> I only use a standard loop device as same as char device use "/dev/null".
>

Right, sorry, missed that.
It is generally better not to define 1024 array on the stack.
Most LTP tests define test path vars as static char arrays in top of test file.


>
>
> >
> >>          if (access(FILE_DIR_PATH, F_OK) == -1)
> >>                  SAFE_MKDIR(FILE_DIR_PATH, 0777);
> >> +       /*
> >> +        * call tst_find_free_loopdev(), avoid overwriting its
> >> +        * content on used loopdev.
> >> +        */
> >> +       loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
> >> +
> >> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
> >>
> >>          fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
> >>          fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
> >>          fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> >> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> >>          fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
> >>          fd_closed = -1;
> >>          fd_append = SAFE_OPEN(FILE_DEST_PATH,
> >>                          O_RDWR | O_CREAT | O_APPEND, 0664);
> >> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
> >> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
> >> +
> >> +       if (loop_devn == -1)
> >> +               fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
> >> +
>        I use the dev_path string.

(loop_devn != 1) ??

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  8:08                                             ` Amir Goldstein
@ 2019-07-25 10:13                                               ` Yang Xu
  2019-07-25 11:02                                                 ` Amir Goldstein
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-25 10:13 UTC (permalink / raw)
  To: ltp

on 2019/07/25 16:08, Amir Goldstein wrote:

> On Thu, Jul 25, 2019 at 8:44 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>  wrote:
>> on 2019/07/25 13:24, Amir Goldstein wrote:
>>
>>> On Thu, Jul 25, 2019 at 8:02 AM Yang Xu<xuyang2018.jy@cn.fujitsu.com>   wrote:
>>>>
>>>>    static void setup(void)
>>>>    {
>>>>           syscall_info();
>>>> +       char dev_path[1024];
>>> Why? What is the point of filling this string if you're not going to
>>> use it. That's exactly what tst_find_free_loopdev(NULL, 0) is for.
>>> I don't think you understood Cyril's comment about the API
>>> correctly.
>>> He meant he rather keep the *option* in the API to fill out the
>>> suggested loopdev file name. Not that you *have* to fill it.
>>>
>>> Thanks,
>>> Amir.
>>>
>> Hi Amir
>>
>>    I think you don't see the whole patch.
>>
>>    I use this dev_path as below:
>>
>>    fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
>>
>> on v5 patch, I use  tst_find_free_loopdev(NULL, 0) and create a customized loop dev named "file_block" by mknod .
>>
>> But why we don't use a path directly filled by tst_find_free_loopdev(dev_path, len)? It will not change lib internal state or overwirte data.
>>
>> I only use a standard loop device as same as char device use "/dev/null".
>>
> Right, sorry, missed that.
> It is generally better not to define 1024 array on the stack.
> Most LTP tests define test path vars as static char arrays in top of test file.
Hi Amir

  I think it is a code-style preference. IMO, 1024 array is not enough large and this function is not
interate or recursion call.  It don't make stack overflow. Also, this test path is only used in setup().
  So, I think keeping it is no problem.

>
>>
>>>>           if (access(FILE_DIR_PATH, F_OK) == -1)
>>>>                   SAFE_MKDIR(FILE_DIR_PATH, 0777);
>>>> +       /*
>>>> +        * call tst_find_free_loopdev(), avoid overwriting its
>>>> +        * content on used loopdev.
>>>> +        */
>>>> +       loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
>>>> +
>>>> +       SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
>>>>
>>>>           fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>>>>           fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>>>>           fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
>>>> -       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>>>>           fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>>>>           fd_closed = -1;
>>>>           fd_append = SAFE_OPEN(FILE_DEST_PATH,
>>>>                           O_RDWR | O_CREAT | O_APPEND, 0664);
>>>> +       fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
>>>> +       fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
>>>> +
>>>> +       if (loop_devn == -1)
>>>> +               fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
>>>> +
>>         I use the dev_path string.
> (loop_devn != 1) ??
Sorry for the obvious error.


Hi Cyril

Would you mind me to send a v7 patch or you merge this patchset with changing this obvious error
if you think it is ok?


> Thanks,
> Amir.
>
>
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25 10:13                                               ` Yang Xu
@ 2019-07-25 11:02                                                 ` Amir Goldstein
  0 siblings, 0 replies; 86+ messages in thread
From: Amir Goldstein @ 2019-07-25 11:02 UTC (permalink / raw)
  To: ltp

> > Right, sorry, missed that.
> > It is generally better not to define 1024 array on the stack.
> > Most LTP tests define test path vars as static char arrays in top of test file.
> Hi Amir
>
>   I think it is a code-style preference. IMO, 1024 array is not enough large and this function is not
> interate or recursion call.  It don't make stack overflow. Also, this test path is only used in setup().
>   So, I think keeping it is no problem.
>

Totally agree. It's a matter of coding style so up to project maintainer to
enforce it. I don't mind. Personally, I just prefer to use the code style of
the project I am contributing to.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev()
  2019-07-25  5:01                                     ` [LTP] [PATCH v6 " Yang Xu
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-29 13:01                                       ` Cyril Hrubis
  2019-07-30 10:42                                         ` Yang Xu
  2 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-29 13:01 UTC (permalink / raw)
  To: ltp

Hi!
> +int tst_find_free_loopdev(const char *path, size_t path_len);
>  /*
>   * Reads test block device stat file and returns the bytes written since the
>   * last call of this function.
> diff --git a/lib/tst_device.c b/lib/tst_device.c
> index 65fcc1337..f2516fb08 100644
> --- a/lib/tst_device.c
> +++ b/lib/tst_device.c
> @@ -53,22 +53,22 @@ static const char *dev_variants[] = {
>  	"/dev/block/loop%i"
>  };
>  
> -static int set_dev_path(int dev)
> +static int set_dev_path(int dev, char *path, size_t path_len)
>  {
>  	unsigned int i;
>  	struct stat st;
>  
>  	for (i = 0; i < ARRAY_SIZE(dev_variants); i++) {
> -		snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
> +		snprintf(path, path_len, dev_variants[i], dev);
>  
> -		if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode))
> +		if (stat(path, &st) == 0 && S_ISBLK(st.st_mode))
>  			return 1;
>  	}
>  
>  	return 0;
>  }
>  
> -static int find_free_loopdev(void)
> +int tst_find_free_loopdev(char *path, size_t path_len)
>  {
>  	int ctl_fd, dev_fd, rc, i;
>  	struct loop_info loopinfo;
> @@ -80,12 +80,14 @@ static int find_free_loopdev(void)
>  		rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
>  		close(ctl_fd);
>  		if (rc >= 0) {
> -			set_dev_path(rc);
> -			tst_resm(TINFO, "Found free device '%s'", dev_path);
> -			return 0;
> +			if (path)
> +				set_dev_path(rc, path, path_len);
> +			tst_resm(TINFO, "Found free device %d '%s'",
> +				rc, path ?: "");
> +			return rc;
>  		}
>  		tst_resm(TINFO, "Couldn't find free loop device");
> -		return 1;
> +		return -1;
>  	}
>  
>  	switch (errno) {
> @@ -104,24 +106,24 @@ static int find_free_loopdev(void)
>  	 * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
>  	 * LOOP_GET_STATUS ioctl() which fails for free loop devices.
>  	 */
> -	for (i = 0; i < 256; i++) {
> +	for (i = 0; path && i < 256; i++) {

There is still a small problem here in the fallback code for older
kernels. The way we detect a free device there is by opening the device
and doing the LOOP_GET_STATUS ioctl(). So by disabling this loop if path
is not set we broke the detection on older kernels when NULL is passed
to the function.

We should work with a local temporary path in this loop and copy it over
to the path if we are succesfull and if path is not NULL.

> -		if (!set_dev_path(i))
> +		if (!set_dev_path(i, path, path_len))
>  			continue;
>  
> -		dev_fd = open(dev_path, O_RDONLY);
> +		dev_fd = open(path, O_RDONLY);
>  
>  		if (dev_fd < 0)
>  			continue;
>  
>  		if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) {
> -			tst_resm(TINFO, "Device '%s' in use", dev_path);
> +			tst_resm(TINFO, "Device '%s' in use", path);
>  		} else {
>  			if (errno != ENXIO)
>  				continue;
> -			tst_resm(TINFO, "Found free device '%s'", dev_path);
> +			tst_resm(TINFO, "Found free device '%s'", path);
>  			close(dev_fd);
> -			return 0;
> +			return i;
>  		}
>  
>  		close(dev_fd);
> @@ -129,7 +131,7 @@ static int find_free_loopdev(void)
>  
>  	tst_resm(TINFO, "No free devices found");
>  
> -	return 1;
> +	return -1;
>  }

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-17  9:44                             ` [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-29 13:56                               ` Petr Vorel
  2019-07-29 13:59                                 ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-29 13:56 UTC (permalink / raw)
  To: ltp

Hi,
> Amir has relaxed cross-device constraint since kernel commit 5dae222a5(vfs:
> allow copy_file_range to copy across devices), I think we can test it in
> copy_file_range01.

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>

Whole patchset LGTM, but here we got quite a lot of failures after increasing
test coverage with .all_filesystems = 1 (which use should be noted in commit
message):

copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
...
copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-29 13:56                               ` Petr Vorel
@ 2019-07-29 13:59                                 ` Petr Vorel
  0 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-29 13:59 UTC (permalink / raw)
  To: ltp

Hi,

> Hi,
> > Amir has relaxed cross-device constraint since kernel commit 5dae222a5(vfs:
> > allow copy_file_range to copy across devices), I think we can test it in
> > copy_file_range01.

> > Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> > Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> Whole patchset LGTM, but here we got quite a lot of failures after increasing
> test coverage with .all_filesystems = 1 (which use should be noted in commit
> message):

> copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
> ...
> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
I'm sorry this was meant to be sent for v6.

> Kind regards,
> Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-29 14:00                                         ` Petr Vorel
  2019-07-29 14:10                                           ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-29 14:00 UTC (permalink / raw)
  To: ltp

Hi,

> Amir has relaxed cross-device constraint since commit[1], I think we can test it in
> copy_file_range01.

> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Now sent to the correct patchset version:

Whole patchset LGTM, but here we got quite a lot of failures after increasing
test coverage with .all_filesystems = 1 (which use should be noted in commit
message):

copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
...
copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-29 14:00                                         ` Petr Vorel
@ 2019-07-29 14:10                                           ` Petr Vorel
  2019-07-30  8:31                                             ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-29 14:10 UTC (permalink / raw)
  To: ltp

Hi,

> > Amir has relaxed cross-device constraint since commit[1], I think we can test it in
> > copy_file_range01.

> > [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

> > Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> > Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> Now sent to the correct patchset version:

> Whole patchset LGTM, but here we got quite a lot of failures after increasing
> test coverage with .all_filesystems = 1 (which use should be noted in commit
> message):

> copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
> ...
> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16

Also .mount_device = 1 and .all_filesystems = 1 require
.needs_root = 1 definition or you get

tst_device.c:97: INFO: Not allowed to open /dev/loop-control. Are you root?: EACCES
tst_device.c:132: INFO: No free devices found
tst_device.c:308: BROK: Failed to acquire device

BTW I wonder whether these could be detected automatically.

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-29 14:10                                           ` Petr Vorel
@ 2019-07-30  8:31                                             ` Yang Xu
  2019-07-30 13:35                                               ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-30  8:31 UTC (permalink / raw)
  To: ltp


> Hi,
>
>>> Amir has relaxed cross-device constraint since commit[1], I think we can test it in
>>> copy_file_range01.
>>> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
>>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>>> Reviewed-by: Amir Goldstein<amir73il@gmail.com>
>> Now sent to the correct patchset version:
>> Whole patchset LGTM, but here we got quite a lot of failures after increasing
>> test coverage with .all_filesystems = 1 (which use should be noted in commit
>> message):
>> copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
>> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
>> ...
>> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
Hi Petr
can you give more information? such as distros, filesystem, envrionment,  do you get 16(EBUSY) on all filesystems?
Because on my machine, I get the following result on 4.18.0-80.el8.x86_64(I test on vfat, extN,xfs,btrfs).

copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0


> Also .mount_device = 1 and .all_filesystems = 1 require
> .needs_root = 1 definition or you get
>
> tst_device.c:97: INFO: Not allowed to open /dev/loop-control. Are you root?: EACCES
> tst_device.c:132: INFO: No free devices found
> tst_device.c:308: BROK: Failed to acquire device
>
> BTW I wonder whether these could be detected automatically.
Here needs root because /dev/loop-control needs it.  But it doesn't represent mount_device and all_filesystems
  need root.
Or, I misunderstand your idea?

> Kind regards,
> Petr
>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev()
  2019-07-29 13:01                                       ` [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev() Cyril Hrubis
@ 2019-07-30 10:42                                         ` Yang Xu
  2019-07-30 11:05                                           ` Cyril Hrubis
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-30 10:42 UTC (permalink / raw)
  To: ltp


> Hi!
>> +int tst_find_free_loopdev(const char *path, size_t path_len);
>>   /*
>>    * Reads test block device stat file and returns the bytes written since the
>>    * last call of this function.
>> diff --git a/lib/tst_device.c b/lib/tst_device.c
>> index 65fcc1337..f2516fb08 100644
>> --- a/lib/tst_device.c
>> +++ b/lib/tst_device.c
>> @@ -53,22 +53,22 @@ static const char *dev_variants[] = {
>>   	"/dev/block/loop%i"
>>   };
>>
>> -static int set_dev_path(int dev)
>> +static int set_dev_path(int dev, char *path, size_t path_len)
>>   {
>>   	unsigned int i;
>>   	struct stat st;
>>
>>   	for (i = 0; i<  ARRAY_SIZE(dev_variants); i++) {
>> -		snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
>> +		snprintf(path, path_len, dev_variants[i], dev);
>>
>> -		if (stat(dev_path,&st) == 0&&  S_ISBLK(st.st_mode))
>> +		if (stat(path,&st) == 0&&  S_ISBLK(st.st_mode))
>>   			return 1;
>>   	}
>>
>>   	return 0;
>>   }
>>
>> -static int find_free_loopdev(void)
>> +int tst_find_free_loopdev(char *path, size_t path_len)
>>   {
>>   	int ctl_fd, dev_fd, rc, i;
>>   	struct loop_info loopinfo;
>> @@ -80,12 +80,14 @@ static int find_free_loopdev(void)
>>   		rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
>>   		close(ctl_fd);
>>   		if (rc>= 0) {
>> -			set_dev_path(rc);
>> -			tst_resm(TINFO, "Found free device '%s'", dev_path);
>> -			return 0;
>> +			if (path)
>> +				set_dev_path(rc, path, path_len);
>> +			tst_resm(TINFO, "Found free device %d '%s'",
>> +				rc, path ?: "");
>> +			return rc;
>>   		}
>>   		tst_resm(TINFO, "Couldn't find free loop device");
>> -		return 1;
>> +		return -1;
>>   	}
>>
>>   	switch (errno) {
>> @@ -104,24 +106,24 @@ static int find_free_loopdev(void)
>>   	 * Older way is to iterate over /dev/loop%i and /dev/loop/%i and try
>>   	 * LOOP_GET_STATUS ioctl() which fails for free loop devices.
>>   	 */
>> -	for (i = 0; i<  256; i++) {
>> +	for (i = 0; path&&  i<  256; i++) {
> There is still a small problem here in the fallback code for older
> kernels. The way we detect a free device there is by opening the device
> and doing the LOOP_GET_STATUS ioctl(). So by disabling this loop if path
> is not set we broke the detection on older kernels when NULL is passed
> to the function.
>
> We should work with a local temporary path in this loop and copy it over
> to the path if we are succesfull and if path is not NULL.
>
Hi Cyril

Thanks for pointing out it.  I will fix it on next version. as below:

int tst_find_free_loopdev(char *path, size_t path_len)
  {
         int ctl_fd, dev_fd, rc, i;
         struct loop_info loopinfo;
+       char buf[1024];

         /* since Linux 3.1 */
         ctl_fd = open(LOOP_CONTROL_FILE, O_RDWR);
@@ -80,12 +81,14 @@ static int find_free_loopdev(void)
                 rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
                 close(ctl_fd);
                 if (rc>= 0) {
-                       set_dev_path(rc);
-                       tst_resm(TINFO, "Found free device '%s'", dev_path);
-                       return 0;
+                       if (path)
+                               set_dev_path(rc, path, path_len);
+                       tst_resm(TINFO, "Found free device %d '%s'",
+                               rc, path ?: "");
+                       return rc;
                 }
                 tst_resm(TINFO, "Couldn't find free loop device");
-               return 1;
+               return -1;
         }


  static int find_free_loopdev(void)
          */
         for (i = 0; i<  256; i++) {

-               if (!set_dev_path(i))
+               if (!set_dev_path(i, buf, sizeof(buf)))
                         continue;

-               dev_fd = open(dev_path, O_RDONLY);
+               dev_fd = open(buf, O_RDONLY);

                 if (dev_fd<  0)
                         continue;

                 if (ioctl(dev_fd, LOOP_GET_STATUS,&loopinfo) == 0) {
-                       tst_resm(TINFO, "Device '%s' in use", dev_path);
+                       tst_resm(TINFO, "Device '%s' in use", buf);
                 } else {
                         if (errno != ENXIO)
                                 continue;
-                       tst_resm(TINFO, "Found free device '%s'", dev_path);
+                       tst_resm(TINFO, "Found free device '%s'", buf);
                         close(dev_fd);
-                       return 0;
+                       if (path != NULL)
+                               strcpy(path, buf);
+                       return i;
                 }


Thanks
Yang Xu

>> -		if (!set_dev_path(i))
>> +		if (!set_dev_path(i, path, path_len))
>>   			continue;
>>
>> -		dev_fd = open(dev_path, O_RDONLY);
>> +		dev_fd = open(path, O_RDONLY);
>>
>>   		if (dev_fd<  0)
>>   			continue;
>>
>>   		if (ioctl(dev_fd, LOOP_GET_STATUS,&loopinfo) == 0) {
>> -			tst_resm(TINFO, "Device '%s' in use", dev_path);
>> +			tst_resm(TINFO, "Device '%s' in use", path);
>>   		} else {
>>   			if (errno != ENXIO)
>>   				continue;
>> -			tst_resm(TINFO, "Found free device '%s'", dev_path);
>> +			tst_resm(TINFO, "Found free device '%s'", path);
>>   			close(dev_fd);
>> -			return 0;
>> +			return i;
>>   		}
>>
>>   		close(dev_fd);
>> @@ -129,7 +131,7 @@ static int find_free_loopdev(void)
>>
>>   	tst_resm(TINFO, "No free devices found");
>>
>> -	return 1;
>> +	return -1;
>>   }




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev()
  2019-07-30 10:42                                         ` Yang Xu
@ 2019-07-30 11:05                                           ` Cyril Hrubis
  2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-30 11:05 UTC (permalink / raw)
  To: ltp

Hi!
> +                       if (path != NULL)
> +                               strcpy(path, buf);

This should be at least strncpy() since we have the path length, or we
may as well call set_dev_path(rc, path, path_len) here.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-25  5:01                                       ` [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-25  5:24                                         ` Amir Goldstein
@ 2019-07-30 13:26                                         ` Petr Vorel
  2019-07-31  7:09                                           ` Yang Xu
  1 sibling, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-30 13:26 UTC (permalink / raw)
  To: ltp

Hi,

...
> diff --git a/include/lapi/fs.h b/include/lapi/fs.h
...
> +/* Referred form linux kernel include/linux/fs.h */
> +#ifdef TST_ABI64
> + #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
> +#else
> + #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
Build fails on i386 on Debian stable [1] [2] due PAGE_SHIFT undeclared.
I guess including <sys/user.h> fixes it.

Kind regards,
Petr

[1] https://api.travis-ci.org/v3/job/565467338/log.txt
[2] https://travis-ci.org/pevik/ltp/builds/565467337

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-30  8:31                                             ` Yang Xu
@ 2019-07-30 13:35                                               ` Petr Vorel
  2019-07-31  7:01                                                 ` Yang Xu
  0 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-30 13:35 UTC (permalink / raw)
  To: ltp

Hi,

> > > Whole patchset LGTM, but here we got quite a lot of failures after increasing
> > > test coverage with .all_filesystems = 1 (which use should be noted in commit
> > > message):
> > > copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
> > > copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
> > > ...
> > > copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
> Hi Petr
> can you give more information? such as distros, filesystem, envrionment,  do you get 16(EBUSY) on all filesystems?
> Because on my machine, I get the following result on 4.18.0-80.el8.x86_64(I test on vfat, extN,xfs,btrfs).
Failing on various distros (VM: openSUSE Tumbleweed, Debian stable and testing,
Centos 7; also on real HW openSUSE), fs: ext4, xfs, btrfs, vfat.

I wonder, what I do wrong. I posted whole output of one machine below.

> > Also .mount_device = 1 and .all_filesystems = 1 require
> > .needs_root = 1 definition or you get

> > tst_device.c:97: INFO: Not allowed to open /dev/loop-control. Are you root?: EACCES
> > tst_device.c:132: INFO: No free devices found
> > tst_device.c:308: BROK: Failed to acquire device

> > BTW I wonder whether these could be detected automatically.
> Here needs root because /dev/loop-control needs it.  But it doesn't represent mount_device and all_filesystems
>  need root.
> Or, I misunderstand your idea?
I thought that for some cases it'd be nice, if .needs_root = 1 was added
internally. But probably bad idea, I guess we should be explicit and add it.

Kind regards,
Petr

tst_device.c:86: INFO: Found free device 1 '/dev/loop1'
tst_supported_fs_types.c:60: INFO: Kernel supports ext2
tst_supported_fs_types.c:44: INFO: mkfs.ext2 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports ext3
tst_supported_fs_types.c:44: INFO: mkfs.ext3 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports ext4
tst_supported_fs_types.c:44: INFO: mkfs.ext4 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports xfs
tst_supported_fs_types.c:44: INFO: mkfs.xfs does exist
tst_supported_fs_types.c:60: INFO: Kernel supports btrfs
tst_supported_fs_types.c:44: INFO: mkfs.btrfs does exist
tst_supported_fs_types.c:60: INFO: Kernel supports vfat
tst_supported_fs_types.c:44: INFO: mkfs.vfat does exist
tst_supported_fs_types.c:83: INFO: Filesystem exfat is not supported
tst_supported_fs_types.c:83: INFO: Filesystem ntfs is not supported
tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext2 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=e585e0bd-0e55-4cdc-a37f-ca81411021c3
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext3 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=188ffc43-d712-452d-ba6c-5727457d87d9
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext4 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=3f384ded-2f54-40a5-b43b-826865b3f67e
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=3f088e9f-b153-40f8-813b-661bc5fac6f2
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on btrfs
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with btrfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=807360ba-a49a-4f8b-b088-92dd455858a7
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=b805d82d-c5a2-45d1-9ad3-df7921a36ece
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_supported_fs_types.c:60: INFO: Kernel supports ext2
tst_supported_fs_types.c:44: INFO: mkfs.ext2 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports ext3
tst_supported_fs_types.c:44: INFO: mkfs.ext3 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports ext4
tst_supported_fs_types.c:44: INFO: mkfs.ext4 does exist
tst_supported_fs_types.c:60: INFO: Kernel supports xfs
tst_supported_fs_types.c:44: INFO: mkfs.xfs does exist
tst_supported_fs_types.c:60: INFO: Kernel supports btrfs
tst_supported_fs_types.c:44: INFO: mkfs.btrfs does exist
tst_supported_fs_types.c:60: INFO: Kernel supports vfat
tst_supported_fs_types.c:44: INFO: mkfs.vfat does exist
tst_supported_fs_types.c:83: INFO: Filesystem exfat is not supported
tst_supported_fs_types.c:83: INFO: Filesystem ntfs is not supported
tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext2 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=e95e50e5-abe4-4f74-924f-af25b1a218a8
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext3 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=9bb43d35-e633-4bcb-9110-28d212c06f53
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext4 opts='' extra opts=''
mke2fs 1.45.0 (6-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=52c81016-b46d-41b2-9ee9-4a414c108480
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=f8ecfc5d-1cba-4722-a75e-53a7ff49dd96
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on btrfs
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with btrfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=64581f50-f38d-4ae3-8931-b63f312f26dd
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed
tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop1 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing tst copy_file_range()
tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=c008d9a3-6100-41ee-b430-8e566b7785d4
swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
copy_file_range02.c:89: CONF: swapon binary not installed
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
swapoff: file_swap: swapoff failed: Invalid argument
copy_file_range02.c:89: CONF: swapoff binary not installed

Summary:
passed   96
failed   48
skipped  36
warnings 0

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-30 13:35                                               ` Petr Vorel
@ 2019-07-31  7:01                                                 ` Yang Xu
  2019-07-31  7:47                                                   ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-31  7:01 UTC (permalink / raw)
  To: ltp


> Hi,
>
>>>> Whole patchset LGTM, but here we got quite a lot of failures after increasing
>>>> test coverage with .all_filesystems = 1 (which use should be noted in commit
>>>> message):
>>>> copy_file_range02.c:120: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
>>>> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
>>>> ...
>>>> copy_file_range02.c:126: FAIL: copy_file_range returned wrong value: 16
>> Hi Petr
>> can you give more information? such as distros, filesystem, envrionment,  do you get 16(EBUSY) on all filesystems?
>> Because on my machine, I get the following result on 4.18.0-80.el8.x86_64(I test on vfat, extN,xfs,btrfs).
> Failing on various distros (VM: openSUSE Tumbleweed, Debian stable and testing,
> Centos 7; also on real HW openSUSE), fs: ext4, xfs, btrfs, vfat.
>
> I wonder, what I do wrong. I posted whole output of one machine below.
Hi Petr

You do nothing wrong.  It fails on various distros because the patchset was merged into upstream kernel since 5.2.

I guess it was not merged into any distros stable kernel Now.


patchurl:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

also add xfstests case url:
https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/553{554,564,565}




>>> Also .mount_device = 1 and .all_filesystems = 1 require
>>> .needs_root = 1 definition or you get
>>> tst_device.c:97: INFO: Not allowed to open /dev/loop-control. Are you root?: EACCES
>>> tst_device.c:132: INFO: No free devices found
>>> tst_device.c:308: BROK: Failed to acquire device
>>> BTW I wonder whether these could be detected automatically.
>> Here needs root because /dev/loop-control needs it.  But it doesn't represent mount_device and all_filesystems
>>   need root.
>> Or, I misunderstand your idea?
> I thought that for some cases it'd be nice, if .needs_root = 1 was added
> internally. But probably bad idea, I guess we should be explicit and add it.
> Kind regards,
> Petr
>
> tst_device.c:86: INFO: Found free device 1 '/dev/loop1'
> tst_supported_fs_types.c:60: INFO: Kernel supports ext2
> tst_supported_fs_types.c:44: INFO: mkfs.ext2 does exist
> tst_supported_fs_types.c:60: INFO: Kernel supports ext3
> tst_supported_fs_types.c:44: INFO: mkfs.ext3 does exist
> tst_supported_fs_types.c:60: INFO: Kernel supports ext4
> tst_supported_fs_types.c:44: INFO: mkfs.ext4 does exist
> tst_supported_fs_types.c:60: INFO: Kernel supports xfs
> tst_supported_fs_types.c:44: INFO: mkfs.xfs does exist
> tst_supported_fs_types.c:60: INFO: Kernel supports btrfs
> tst_supported_fs_types.c:44: INFO: mkfs.btrfs does exist
> tst_supported_fs_types.c:60: INFO: Kernel supports vfat
> tst_supported_fs_types.c:44: INFO: mkfs.vfat does exist
> tst_supported_fs_types.c:83: INFO: Filesystem exfat is not supported
> tst_supported_fs_types.c:83: INFO: Filesystem ntfs is not supported
> tst_test.c:1161: INFO: Testing on ext2
> tst_mkfs.c:90: INFO: Formatting /dev/loop1 with ext2 opts='' extra opts=''
> mke2fs 1.45.0 (6-Mar-2019)
> tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
> copy_file_range.h:41: INFO: Testing libc copy_file_range()
> tst_device.c:86: INFO: Found free device 2 '/dev/loop2'
> Setting up swapspace version 1, size = 36 KiB (36864 bytes)
> no label, UUID=e585e0bd-0e55-4cdc-a37f-ca81411021c3
> swapon: /tmp/wTdW10/file_swap: swapon failed: Invalid argument
  I am curious about why swapon got this error.

> copy_file_range02.c:89: CONF: swapon binary not installed
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EISDIR
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EBADF
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
> copy_file_range02.c:105: CONF: filesystem doesn't support swapfile, skip it
> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
> copy_file_range02.c:118: PASS: copy_file_range failed as expected: EINVAL
> copy_file_range02.c:122: FAIL: copy_file_range failed unexpectedly; expected EOVERFLOW, but got: EINVAL
> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 0
> swapoff: file_swap: swapoff failed: Invalid argument
> copy_file_range02.c:89: CONF: swapoff binary not installed
>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-30 13:26                                         ` Petr Vorel
@ 2019-07-31  7:09                                           ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-31  7:09 UTC (permalink / raw)
  To: ltp


> Hi,
>
> ...
>> diff --git a/include/lapi/fs.h b/include/lapi/fs.h
> ...
>> +/* Referred form linux kernel include/linux/fs.h */
>> +#ifdef TST_ABI64
>> + #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
>> +#else
>> + #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX<<  PAGE_SHIFT)
> Build fails on i386 on Debian stable [1] [2] due PAGE_SHIFT undeclared.
> I guess including<sys/user.h>  fixes it.
>
Hi Petr

  Thanks for you pointing out it.  I will include this header file.


> Kind regards,
> Petr
>
> [1] https://api.travis-ci.org/v3/job/565467338/log.txt
> [2] https://travis-ci.org/pevik/ltp/builds/565467337
>
>
> .
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-31  7:01                                                 ` Yang Xu
@ 2019-07-31  7:47                                                   ` Petr Vorel
  0 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-31  7:47 UTC (permalink / raw)
  To: ltp

Hi Xu,

> > I wonder, what I do wrong. I posted whole output of one machine below.
> Hi Petr

> You do nothing wrong.  It fails on various distros because the patchset was merged into upstream kernel since 5.2.

> I guess it was not merged into any distros stable kernel Now.
Thanks for info. I looked into commits during review, but didn't pay attention
when it was merged into mainline.


> patchurl:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

> also add xfstests case url:
> https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/553{554,564,565}
https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/{553,554,564,565}

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-30 11:05                                           ` Cyril Hrubis
@ 2019-07-31 10:40                                             ` Yang Xu
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
                                                                 ` (3 more replies)
  0 siblings, 4 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-31 10:40 UTC (permalink / raw)
  To: ltp

Alter find_free_loopdev() to tst_find_free_loopdev(path, path_len),
tst_acquire_device() passes the dev_path and path_len inside of
the tst_device.c. It returns the free loopdev minor (and -1 for no
free loopdev). If path is non-NULL, it will be filled with free
loopdev path. We also can call tst_find_free_loopdev(NULL, 0) to
make a customized loopdev by using mkdnod.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
-------
v6->v7:
     correct logic when use old detection way
---
---
 doc/test-writing-guidelines.txt | 12 +++++++++++
 include/tst_device.h            |  6 ++++++
 lib/tst_device.c                | 35 +++++++++++++++++++--------------
 3 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index e59d72065..d21fbf76a 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -1053,6 +1053,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
 -------------------------------------------------------------------------------
 #include "tst_test.h"
 
+int tst_find_free_loopdev(const char *path, size_t path_len);
+-------------------------------------------------------------------------------
+
+This function finds a free loopdev and returns the free loopdev minor (-1 for no
+free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+If you want to use a customized loop device, we can call tst_find_free_loopdev
+(NULL, 0) in tests to get a free minor number. Then mknod.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include "tst_test.h"
+
 unsigned long tst_dev_bytes_written(const char *dev);
 -------------------------------------------------------------------------------
 
diff --git a/include/tst_device.h b/include/tst_device.h
index 61902b7e0..f0ddc3e93 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -44,6 +44,12 @@ int tst_umount(const char *path);
  */
 int tst_clear_device(const char *dev);
 
+/*
+ * Finds a free loop device for use and returns the free loopdev minor(-1 for no
+ * free loopdev). If path is non-NULL, it will be filled with free loopdev path.
+ *
+ */
+int tst_find_free_loopdev(const char *path, size_t path_len);
 /*
  * Reads test block device stat file and returns the bytes written since the
  * last call of this function.
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 65fcc1337..3eb51bee1 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -53,25 +53,26 @@ static const char *dev_variants[] = {
 	"/dev/block/loop%i"
 };
 
-static int set_dev_path(int dev)
+static int set_dev_path(int dev, char *path, size_t path_len)
 {
 	unsigned int i;
 	struct stat st;
 
 	for (i = 0; i < ARRAY_SIZE(dev_variants); i++) {
-		snprintf(dev_path, sizeof(dev_path), dev_variants[i], dev);
+		snprintf(path, path_len, dev_variants[i], dev);
 
-		if (stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode))
+		if (stat(path, &st) == 0 && S_ISBLK(st.st_mode))
 			return 1;
 	}
 
 	return 0;
 }
 
-static int find_free_loopdev(void)
+int tst_find_free_loopdev(char *path, size_t path_len)
 {
 	int ctl_fd, dev_fd, rc, i;
 	struct loop_info loopinfo;
+	char buf[1024];
 
 	/* since Linux 3.1 */
 	ctl_fd = open(LOOP_CONTROL_FILE, O_RDWR);
@@ -80,12 +81,14 @@ static int find_free_loopdev(void)
 		rc = ioctl(ctl_fd, LOOP_CTL_GET_FREE);
 		close(ctl_fd);
 		if (rc >= 0) {
-			set_dev_path(rc);
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
-			return 0;
+			if (path)
+				set_dev_path(rc, path, path_len);
+			tst_resm(TINFO, "Found free device %d '%s'",
+				rc, path ?: "");
+			return rc;
 		}
 		tst_resm(TINFO, "Couldn't find free loop device");
-		return 1;
+		return -1;
 	}
 
 	switch (errno) {
@@ -106,22 +109,24 @@ static int find_free_loopdev(void)
 	 */
 	for (i = 0; i < 256; i++) {
 
-		if (!set_dev_path(i))
+		if (!set_dev_path(i, buf, sizeof(buf)))
 			continue;
 
-		dev_fd = open(dev_path, O_RDONLY);
+		dev_fd = open(buf, O_RDONLY);
 
 		if (dev_fd < 0)
 			continue;
 
 		if (ioctl(dev_fd, LOOP_GET_STATUS, &loopinfo) == 0) {
-			tst_resm(TINFO, "Device '%s' in use", dev_path);
+			tst_resm(TINFO, "Device '%s' in use", buf);
 		} else {
 			if (errno != ENXIO)
 				continue;
-			tst_resm(TINFO, "Found free device '%s'", dev_path);
+			tst_resm(TINFO, "Found free device '%s'", buf);
 			close(dev_fd);
-			return 0;
+			if (path != NULL)
+				strncpy(path, buf, path_len);
+			return i;
 		}
 
 		close(dev_fd);
@@ -129,7 +134,7 @@ static int find_free_loopdev(void)
 
 	tst_resm(TINFO, "No free devices found");
 
-	return 1;
+	return -1;
 }
 
 static int attach_device(const char *dev, const char *file)
@@ -274,7 +279,7 @@ const char *tst_acquire_device__(unsigned int size)
 		return NULL;
 	}
 
-	if (find_free_loopdev())
+	if (tst_find_free_loopdev(dev_path, sizeof(dev_path)) == -1)
 		return NULL;
 
 	if (attach_device(dev_path, DEV_FILE))
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
@ 2019-07-31 10:40                                               ` Yang Xu
  2019-07-31 12:28                                                 ` Petr Vorel
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
                                                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-07-31 10:40 UTC (permalink / raw)
  To: ltp

Amir has relaxed cross-device constraint since commit[1], I think we can test it in
copy_file_range01.

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../copy_file_range/copy_file_range01.c       | 58 ++++++++++++++-----
 1 file changed, 43 insertions(+), 15 deletions(-)

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 a5bd5e7f7..ec55e5da1 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range01.c
@@ -24,7 +24,16 @@
 
 static int page_size;
 static int errcount, numcopies;
-static int fd_in, fd_out;
+static int fd_in, fd_out, cross_sup;
+
+static struct tcase {
+	char    *path;
+	int     flags;
+	char    *message;
+} tcases[] = {
+	{FILE_DEST_PATH,  0, "non cross-device"},
+	{FILE_MNTED_PATH, 1, "cross-device"},
+};
 
 static int check_file_content(const char *fname1, const char *fname2,
 	loff_t *off1, loff_t *off2, size_t len)
@@ -90,7 +99,7 @@ static int check_file_offset(const char *m, int fd, loff_t len,
 	return ret;
 }
 
-static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
+static void test_one(size_t len, loff_t *off_in, loff_t *off_out, char *path)
 {
 	int ret;
 	size_t to_copy = len;
@@ -131,7 +140,7 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 		to_copy -= TST_RET;
 	} while (to_copy > 0);
 
-	ret = check_file_content(FILE_SRC_PATH, FILE_DEST_PATH,
+	ret = check_file_content(FILE_SRC_PATH, path,
 		off_in, off_out, len);
 	if (ret) {
 		tst_res(TFAIL, "file contents do not match");
@@ -149,10 +158,10 @@ static void test_one(size_t len, loff_t *off_in, loff_t *off_out)
 	}
 }
 
-static void open_files(void)
+static void open_files(char *path)
 {
 	fd_in  = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY);
-	fd_out = SAFE_OPEN(FILE_DEST_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+	fd_out = SAFE_OPEN(path, O_CREAT | O_WRONLY | O_TRUNC, 0644);
 }
 
 static void close_files(void)
@@ -163,9 +172,16 @@ static void close_files(void)
 		SAFE_CLOSE(fd_in);
 }
 
-static void copy_file_range_verify(void)
+static void copy_file_range_verify(unsigned int n)
 {
 	int i, j, k;
+	struct tcase *tc = &tcases[n];
+
+	if (tc->flags && !cross_sup) {
+		tst_res(TCONF,
+			"copy_file_range doesn't support cross-device, skip it");
+		return;
+	}
 
 	errcount = numcopies = 0;
 	size_t len_arr[]	= {11, page_size-1, page_size, page_size+1};
@@ -182,33 +198,41 @@ static void copy_file_range_verify(void)
 	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]);
+				open_files(tc->path);
+				test_one(len_arr[i], off_arr[j], off_arr[k], tc->path);
 				close_files();
 				numcopies++;
 			}
 
 	if (errcount == 0)
 		tst_res(TPASS,
-			"copy_file_range completed all %d copy jobs successfully!",
-			numcopies);
+			"%s copy_file_range completed all %d copy jobs successfully!",
+			tc->message, numcopies);
 	else
-		tst_res(TFAIL, "copy_file_range failed %d of %d copy jobs.",
-				errcount, numcopies);
+		tst_res(TFAIL, "%s copy_file_range failed %d of %d copy jobs.",
+			tc->message, errcount, numcopies);
 }
 
 static void setup(void)
 {
-	int i, fd;
+	int i, fd, fd_test;
 
 	syscall_info();
 
 	page_size = getpagesize();
-
+	cross_sup = 1;
 	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, CONTSIZE);
+
+	fd_test = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
+	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
+	if (TST_ERR == EXDEV)
+		cross_sup = 0;
+
+	SAFE_CLOSE(fd_test);
+	remove(FILE_MNTED_PATH);
 	SAFE_CLOSE(fd);
 }
 
@@ -220,7 +244,11 @@ static void cleanup(void)
 static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
 	.needs_tmpdir = 1,
-	.test_all = copy_file_range_verify,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.test = copy_file_range_verify,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-31 10:40                                               ` Yang Xu
  2019-07-31 12:28                                                 ` Petr Vorel
  2019-08-05  6:58                                                 ` Murphy Zhou
  2019-07-31 12:05                                               ` [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev() Petr Vorel
  2019-07-31 12:07                                               ` Petr Vorel
  3 siblings, 2 replies; 86+ messages in thread
From: Yang Xu @ 2019-07-31 10:40 UTC (permalink / raw)
  To: ltp

Since Amir patch[1] for copy_file_range has been merged into upstream
kernel, we should add swapfile, immutable file, bounds tests in ltp.
Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
constraint has been relaxed since[2]). I follow xfstests code[3].

[1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
[2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
[3]https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/(553,554,564,565}

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>

----
v5->v6:
   1)directly use the tst_find_free_loopdev filling dev_path
   2)use TST_ABI64 instead of __WORDSIZE == 64
v6->v7:
    fix undefined PAGE_SHIFT build error
---
---
 include/lapi/fs.h                             |   9 ++
 .../copy_file_range/copy_file_range.h         |  13 +-
 .../copy_file_range/copy_file_range02.c       | 145 +++++++++++++++---
 3 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/include/lapi/fs.h b/include/lapi/fs.h
index 42cb4f9b2..1af55628c 100644
--- a/include/lapi/fs.h
+++ b/include/lapi/fs.h
@@ -7,6 +7,8 @@
 #ifdef HAVE_LINUX_FS_H
 # include <linux/fs.h>
 #endif
+# include <sys/user.h>
+# include "lapi/abisize.h"
 
 #ifndef LAPI_FS_H
 #define LAPI_FS_H
@@ -35,4 +37,11 @@
 #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
 #endif
 
+/* Referred form linux kernel include/linux/fs.h */
+#ifdef TST_ABI64
+ #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
+#else
+ #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
+#endif
+
 #endif
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
index b6d132978..c7f423e45 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
@@ -9,7 +9,10 @@
 
 #include <stdbool.h>
 #include <unistd.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
 #include "lapi/syscalls.h"
+#include "lapi/fs.h"
 
 #define TEST_VARIANTS	2
 
@@ -18,10 +21,18 @@
 #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
+#define FILE_IMMUTABLE_PATH "file_immutable"
+#define FILE_SWAP_PATH "file_swap"
+#define FILE_CHRDEV    "/dev/null"
+#define FILE_FIFO      "file_fifo"
+#define FILE_COPY_PATH  "file_copy"
 
 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
 #define CONTSIZE	(sizeof(CONTENT) - 1)
+#define MAX_LEN   MAX_LFS_FILESIZE
+#define MIN_OFF   65537
+#define MAX_OFF   (MAX_LEN - MIN_OFF)
 
 static void syscall_info(void)
 {
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 07c0207c2..36976156e 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -10,15 +10,25 @@
  *
  * 1) Try to copy contents to file open as readonly
  *    -> EBADF
- * 2) Try to copy contents to file on different mounted
- *    filesystem -> EXDEV
- * 3) Try to copy contents to directory -> EISDIR
- * 4) Try to copy contents to a file opened with the
+ * 2) Try to copy contents to directory -> EISDIR
+ * 3) Try to copy contents to a file opened with the
  *    O_APPEND flag -> EBADF
- * 5) Try to copy contents to closed filedescriptor
+ * 4) Try to copy contents to closed filedescriptor
  *    -> EBADF
- * 6) Try to copy contents with invalid 'flags' value
+ * 5) Try to copy contents with invalid 'flags' value
  *    -> EINVAL
+ * 6) Try to copy contents to a file chattred with +i
+ *    flag -> EPERM
+ * 7) Try to copy contents to a swapfile ->ETXTBSY
+ * 8) Try to copy contents to the samefile with overlapping
+ *    ->EINVAL
+ * 9) Try to copy contents to a blkdev ->EINVAL
+ * 10) Try to copy contents to a chardev ->EINVAL
+ * 11) Try to copy contents to a FIFO ->EINVAL
+ * 12) Try to copy contents to a file with length beyond
+ *     16EiB wraps around 0 -> EOVERFLOW
+ * 13) Try to copy contents to a file with target file range
+ *     beyond maximum supported file size ->EFBIG
  */
 
 #define _GNU_SOURCE
@@ -29,30 +39,78 @@
 static int fd_src;
 static int fd_dest;
 static int fd_rdonly;
-static int fd_mnted;
 static int fd_dir;
 static int fd_closed;
 static int fd_append;
+static int fd_immutable;
+static int fd_swapfile;
+static int fd_dup;
+static int fd_blkdev;
+static int fd_chrdev;
+static int fd_fifo;
+static int fd_copy;
+
+static int chattr_i_nsup;
+static int swap_nsup;
+static int loop_devn;
 
 static struct tcase {
 	int	*copy_to_fd;
 	int	flags;
 	int	exp_err;
+	loff_t  dst;
+	loff_t     len;
 } tcases[] = {
-	{&fd_rdonly,	0,	EBADF},
-	{&fd_mnted,	0,	EXDEV},
-	{&fd_dir,	0,	EISDIR},
-	{&fd_append,	0,	EBADF},
-	{&fd_closed,	0,	EBADF},
-	{&fd_dest,	-1,	EINVAL},
+	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
+	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
+	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
+	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
+	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
+	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
+	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
+	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
+	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
+	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };
 
+static int run_command(char *command, char *option, char *file)
+{
+	const char *const cmd[] = {command, option, file, NULL};
+	int ret;
+
+	ret = tst_run_cmd(cmd, NULL, NULL, 1);
+	switch (ret) {
+	case 0:
+	return 0;
+	case 255:
+		tst_res(TCONF, "%s binary not installed", command);
+	return 1;
+	default:
+		tst_res(TCONF, "%s exited with %i", command, ret);
+	return 2;
+	}
+}
+
 static void verify_copy_file_range(unsigned int n)
 {
 	struct tcase *tc = &tcases[n];
-
+	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
+		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
+		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
+		return;
+	}
+	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
+		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
+		return;
+	}
 	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
-				0, CONTSIZE, tc->flags));
+				&tc->dst, tc->len, tc->flags));
 
 	if (TST_RET == -1) {
 		if (tc->exp_err == TST_ERR) {
@@ -76,33 +134,80 @@ static void cleanup(void)
 		SAFE_CLOSE(fd_append);
 	if (fd_dir > 0)
 		SAFE_CLOSE(fd_dir);
-	if (fd_mnted > 0)
-		SAFE_CLOSE(fd_mnted);
 	if (fd_rdonly > 0)
 		SAFE_CLOSE(fd_rdonly);
 	if (fd_dest > 0)
 		SAFE_CLOSE(fd_dest);
 	if (fd_src > 0)
 		SAFE_CLOSE(fd_src);
+	if (fd_immutable > 0) {
+		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
+		SAFE_CLOSE(fd_immutable);
+	}
+	if (fd_swapfile > 0) {
+		run_command("swapoff", FILE_SWAP_PATH, NULL);
+		SAFE_CLOSE(fd_swapfile);
+	}
+	if (fd_dup > 0)
+		SAFE_CLOSE(fd_dup);
+	if (fd_copy > 0)
+		SAFE_CLOSE(fd_copy);
+	SAFE_UNLINK(FILE_FIFO);
 }
 
 static void setup(void)
 {
 	syscall_info();
+	char dev_path[1024];
 
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
+	/*
+	 * call tst_find_free_loopdev(), avoid overwriting its
+	 * content on used loopdev.
+	 */
+	loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
+
+	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
 
 	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
 	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
-	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
 	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
 	fd_closed = -1;
 	fd_append = SAFE_OPEN(FILE_DEST_PATH,
 			O_RDWR | O_CREAT | O_APPEND, 0664);
+	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
+	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
+
+	if (loop_devn == -1)
+		fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
+
+	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
+	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
+
+	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
+	close(fd_src);
+	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
+	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
+
+	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
+	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+
+	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
+		tst_res(TCONF, "Insufficient disk space to create swap file");
+		swap_nsup = 3;
+		return;
+	}
+
+	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
+		tst_res(TCONF, "Failed to create swapfile");
+		swap_nsup = 4;
+		return;
+	}
 
-	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
+	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
+	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
 }
 
 static struct tst_test test = {
@@ -113,6 +218,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mount_device = 1,
 	.mntpoint = MNTPOINT,
-	.dev_fs_type = "ext4",
+	.all_filesystems = 1,
 	.test_variants = TEST_VARIANTS,
 };
-- 
2.18.1




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-31 12:05                                               ` Petr Vorel
  2019-07-31 12:28                                                 ` Cyril Hrubis
  2019-07-31 12:07                                               ` Petr Vorel
  3 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 12:05 UTC (permalink / raw)
  To: ltp

Hi Xu,

Reviewed-by: Petr Vorel <pvorel@suse.cz>

...
> +++ b/lib/tst_device.c
...
> -			return 0;
> +			if (path != NULL)
> +				strncpy(path, buf, path_len);
Is it safe to assume that path_len is *always* < 1024 (size of buf)?
> +			return i;
...


Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
                                                                 ` (2 preceding siblings ...)
  2019-07-31 12:05                                               ` [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev() Petr Vorel
@ 2019-07-31 12:07                                               ` Petr Vorel
  3 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 12:07 UTC (permalink / raw)
  To: ltp

Hi Xu,

...
> +++ b/doc/test-writing-guidelines.txt
> @@ -1053,6 +1053,18 @@ IMPORTANT: All testcases should use 'tst_umount()' instead of 'umount(2)' to
>  -------------------------------------------------------------------------------
>  #include "tst_test.h"

> +int tst_find_free_loopdev(const char *path, size_t path_len);
> +-------------------------------------------------------------------------------
> +
> +This function finds a free loopdev and returns the free loopdev minor (-1 for no
> +free loopdev). If path is non-NULL, it will be filled with free loopdev path.
> +If you want to use a customized loop device, we can call tst_find_free_loopdev
> +(NULL, 0) in tests to get a free minor number. Then mknod.
Maybe (as "Then mknod." is a sentence without a verb):
   (NULL, 0) in tests to get a free minor number and then mknod.

(nitch, of course can be fixed during merge)

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
@ 2019-07-31 12:28                                                 ` Petr Vorel
  0 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 12:28 UTC (permalink / raw)
  To: ltp

Hi,

> Amir has relaxed cross-device constraint since commit[1], I think we can test it in
> copy_file_range01.

> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
@ 2019-07-31 12:28                                                 ` Petr Vorel
  2019-08-05  6:58                                                 ` Murphy Zhou
  1 sibling, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 12:28 UTC (permalink / raw)
  To: ltp

Hi,

> Since Amir patch[1] for copy_file_range has been merged into upstream
> kernel, we should add swapfile, immutable file, bounds tests in ltp.
> Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
> constraint has been relaxed since[2]). I follow xfstests code[3].

> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
> [3]https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/(553,554,564,565}

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 12:05                                               ` [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev() Petr Vorel
@ 2019-07-31 12:28                                                 ` Cyril Hrubis
  2019-07-31 12:48                                                   ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-31 12:28 UTC (permalink / raw)
  To: ltp

Hi!
> ...
> > +++ b/lib/tst_device.c
> ...
> > -			return 0;
> > +			if (path != NULL)
> > +				strncpy(path, buf, path_len);
> Is it safe to assume that path_len is *always* < 1024 (size of buf)?

strncpy() is tricky that it may not null-terminate the string if the
source is too long, I would have just added path[path_len-1] = 0 after
the strncpy() here.

> > +			return i;
> ...
> 
> 
> Kind regards,
> Petr

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 12:28                                                 ` Cyril Hrubis
@ 2019-07-31 12:48                                                   ` Petr Vorel
  2019-07-31 13:25                                                     ` Cyril Hrubis
  0 siblings, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 12:48 UTC (permalink / raw)
  To: ltp

Hi,

> > > -			return 0;
> > > +			if (path != NULL)
> > > +				strncpy(path, buf, path_len);
> > Is it safe to assume that path_len is *always* < 1024 (size of buf)?

> strncpy() is tricky that it may not null-terminate the string if the
> source is too long, I would have just added path[path_len-1] = 0 after
> the strncpy() here.
I was thinking about it as well.
I suggest to merge it with this change (+ tiny change I proposed in docs).


Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 12:48                                                   ` Petr Vorel
@ 2019-07-31 13:25                                                     ` Cyril Hrubis
  2019-07-31 21:06                                                       ` Petr Vorel
  0 siblings, 1 reply; 86+ messages in thread
From: Cyril Hrubis @ 2019-07-31 13:25 UTC (permalink / raw)
  To: ltp

Hi!
> > > > -			return 0;
> > > > +			if (path != NULL)
> > > > +				strncpy(path, buf, path_len);
> > > Is it safe to assume that path_len is *always* < 1024 (size of buf)?
> 
> > strncpy() is tricky that it may not null-terminate the string if the
> > source is too long, I would have just added path[path_len-1] = 0 after
> > the strncpy() here.
> I was thinking about it as well.
> I suggest to merge it with this change (+ tiny change I proposed in docs).

I'm okay with that.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev()
  2019-07-31 13:25                                                     ` Cyril Hrubis
@ 2019-07-31 21:06                                                       ` Petr Vorel
  0 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-07-31 21:06 UTC (permalink / raw)
  To: ltp

Hi,

> Hi!
> > > > > -			return 0;
> > > > > +			if (path != NULL)
> > > > > +				strncpy(path, buf, path_len);
> > > > Is it safe to assume that path_len is *always* < 1024 (size of buf)?

> > > strncpy() is tricky that it may not null-terminate the string if the
> > > source is too long, I would have just added path[path_len-1] = 0 after
> > > the strncpy() here.
> > I was thinking about it as well.
> > I suggest to merge it with this change (+ tiny change I proposed in docs).

> I'm okay with that.
Merged into master with these changes and slightly changed commit messages.

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-07-31 10:40                                               ` [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
  2019-07-31 12:28                                                 ` Petr Vorel
@ 2019-08-05  6:58                                                 ` Murphy Zhou
  2019-08-05  7:11                                                   ` Yang Xu
  1 sibling, 1 reply; 86+ messages in thread
From: Murphy Zhou @ 2019-08-05  6:58 UTC (permalink / raw)
  To: ltp

Hi,

On Wed, Jul 31, 2019 at 06:40:29PM +0800, Yang Xu wrote:
> Since Amir patch[1] for copy_file_range has been merged into upstream
> kernel, we should add swapfile, immutable file, bounds tests in ltp.
> Also, add block,char,pipe dev tests and remove EXDEV test(the cross-device
> constraint has been relaxed since[2]). I follow xfstests code[3].
> 
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96e6e8f4a
> [2]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5dae222a5
> [3]https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/tests/generic/(553,554,564,565}
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> 
> ----
> v5->v6:
>    1)directly use the tst_find_free_loopdev filling dev_path
>    2)use TST_ABI64 instead of __WORDSIZE == 64
> v6->v7:
>     fix undefined PAGE_SHIFT build error
> ---
> ---
>  include/lapi/fs.h                             |   9 ++
>  .../copy_file_range/copy_file_range.h         |  13 +-
>  .../copy_file_range/copy_file_range02.c       | 145 +++++++++++++++---
>  3 files changed, 146 insertions(+), 21 deletions(-)
> 
> diff --git a/include/lapi/fs.h b/include/lapi/fs.h
> index 42cb4f9b2..1af55628c 100644
> --- a/include/lapi/fs.h
> +++ b/include/lapi/fs.h
> @@ -7,6 +7,8 @@
>  #ifdef HAVE_LINUX_FS_H
>  # include <linux/fs.h>
>  #endif
> +# include <sys/user.h>
> +# include "lapi/abisize.h"
>  
>  #ifndef LAPI_FS_H
>  #define LAPI_FS_H
> @@ -35,4 +37,11 @@
>  #define FS_NODUMP_FL	   0x00000040 /* do not dump file */
>  #endif
>  
> +/* Referred form linux kernel include/linux/fs.h */
> +#ifdef TST_ABI64
> + #define MAX_LFS_FILESIZE   ((loff_t)LLONG_MAX)
> +#else
> + #define MAX_LFS_FILESIZE   ((loff_t)ULONG_MAX << PAGE_SHIFT)
> +#endif
> +
>  #endif
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> index b6d132978..c7f423e45 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range.h
> @@ -9,7 +9,10 @@
>  
>  #include <stdbool.h>
>  #include <unistd.h>
> +#include <sys/sysmacros.h>
> +#include <limits.h>
>  #include "lapi/syscalls.h"
> +#include "lapi/fs.h"
>  
>  #define TEST_VARIANTS	2
>  
> @@ -18,10 +21,18 @@
>  #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 FILE_MNTED_PATH  MNTPOINT"/file_mnted"
> +#define FILE_IMMUTABLE_PATH "file_immutable"
> +#define FILE_SWAP_PATH "file_swap"
> +#define FILE_CHRDEV    "/dev/null"
> +#define FILE_FIFO      "file_fifo"
> +#define FILE_COPY_PATH  "file_copy"
>  
>  #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
>  #define CONTSIZE	(sizeof(CONTENT) - 1)
> +#define MAX_LEN   MAX_LFS_FILESIZE
> +#define MIN_OFF   65537
> +#define MAX_OFF   (MAX_LEN - MIN_OFF)
>  
>  static void syscall_info(void)
>  {
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 07c0207c2..36976156e 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -10,15 +10,25 @@
>   *
>   * 1) Try to copy contents to file open as readonly
>   *    -> EBADF
> - * 2) Try to copy contents to file on different mounted
> - *    filesystem -> EXDEV
> - * 3) Try to copy contents to directory -> EISDIR
> - * 4) Try to copy contents to a file opened with the
> + * 2) Try to copy contents to directory -> EISDIR
> + * 3) Try to copy contents to a file opened with the
>   *    O_APPEND flag -> EBADF
> - * 5) Try to copy contents to closed filedescriptor
> + * 4) Try to copy contents to closed filedescriptor
>   *    -> EBADF
> - * 6) Try to copy contents with invalid 'flags' value
> + * 5) Try to copy contents with invalid 'flags' value
>   *    -> EINVAL
> + * 6) Try to copy contents to a file chattred with +i
> + *    flag -> EPERM
> + * 7) Try to copy contents to a swapfile ->ETXTBSY
> + * 8) Try to copy contents to the samefile with overlapping
> + *    ->EINVAL
> + * 9) Try to copy contents to a blkdev ->EINVAL
> + * 10) Try to copy contents to a chardev ->EINVAL
> + * 11) Try to copy contents to a FIFO ->EINVAL
> + * 12) Try to copy contents to a file with length beyond
> + *     16EiB wraps around 0 -> EOVERFLOW
> + * 13) Try to copy contents to a file with target file range
> + *     beyond maximum supported file size ->EFBIG

Test 13) fails on latest Linus tree. Is there any report or working on this?

Thanks!
M

>   */
>  
>  #define _GNU_SOURCE
> @@ -29,30 +39,78 @@
>  static int fd_src;
>  static int fd_dest;
>  static int fd_rdonly;
> -static int fd_mnted;
>  static int fd_dir;
>  static int fd_closed;
>  static int fd_append;
> +static int fd_immutable;
> +static int fd_swapfile;
> +static int fd_dup;
> +static int fd_blkdev;
> +static int fd_chrdev;
> +static int fd_fifo;
> +static int fd_copy;
> +
> +static int chattr_i_nsup;
> +static int swap_nsup;
> +static int loop_devn;
>  
>  static struct tcase {
>  	int	*copy_to_fd;
>  	int	flags;
>  	int	exp_err;
> +	loff_t  dst;
> +	loff_t     len;
>  } tcases[] = {
> -	{&fd_rdonly,	0,	EBADF},
> -	{&fd_mnted,	0,	EXDEV},
> -	{&fd_dir,	0,	EISDIR},
> -	{&fd_append,	0,	EBADF},
> -	{&fd_closed,	0,	EBADF},
> -	{&fd_dest,	-1,	EINVAL},
> +	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE},
> +	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE},
> +	{&fd_append,	0,   EBADF,      0,     CONTSIZE},
> +	{&fd_closed,	0,   EBADF,      0,     CONTSIZE},
> +	{&fd_dest,	-1,  EINVAL,     0,     CONTSIZE},
> +	{&fd_immutable, 0,   EPERM,      0,     CONTSIZE},
> +	{&fd_swapfile,  0,   ETXTBSY,    0,     CONTSIZE},
> +	{&fd_dup,       0,   EINVAL,     0,     CONTSIZE/2},
> +	{&fd_blkdev,    0,   EINVAL,     0,     CONTSIZE},
> +	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
> +	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
> +	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
> +	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
>  
> +static int run_command(char *command, char *option, char *file)
> +{
> +	const char *const cmd[] = {command, option, file, NULL};
> +	int ret;
> +
> +	ret = tst_run_cmd(cmd, NULL, NULL, 1);
> +	switch (ret) {
> +	case 0:
> +	return 0;
> +	case 255:
> +		tst_res(TCONF, "%s binary not installed", command);
> +	return 1;
> +	default:
> +		tst_res(TCONF, "%s exited with %i", command, ret);
> +	return 2;
> +	}
> +}
> +
>  static void verify_copy_file_range(unsigned int n)
>  {
>  	struct tcase *tc = &tcases[n];
> -
> +	if (tc->copy_to_fd == &fd_immutable && chattr_i_nsup) {
> +		tst_res(TCONF, "filesystem doesn't support chattr +i, skip it");
> +		return;
> +	}
> +	if (tc->copy_to_fd == &fd_swapfile && swap_nsup) {
> +		tst_res(TCONF, "filesystem doesn't support swapfile, skip it");
> +		return;
> +	}
> +	if (tc->copy_to_fd == &fd_blkdev && loop_devn == -1) {
> +		tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
> +		return;
> +	}
>  	TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
> -				0, CONTSIZE, tc->flags));
> +				&tc->dst, tc->len, tc->flags));
>  
>  	if (TST_RET == -1) {
>  		if (tc->exp_err == TST_ERR) {
> @@ -76,33 +134,80 @@ static void cleanup(void)
>  		SAFE_CLOSE(fd_append);
>  	if (fd_dir > 0)
>  		SAFE_CLOSE(fd_dir);
> -	if (fd_mnted > 0)
> -		SAFE_CLOSE(fd_mnted);
>  	if (fd_rdonly > 0)
>  		SAFE_CLOSE(fd_rdonly);
>  	if (fd_dest > 0)
>  		SAFE_CLOSE(fd_dest);
>  	if (fd_src > 0)
>  		SAFE_CLOSE(fd_src);
> +	if (fd_immutable > 0) {
> +		run_command("chattr", "-i", FILE_IMMUTABLE_PATH);
> +		SAFE_CLOSE(fd_immutable);
> +	}
> +	if (fd_swapfile > 0) {
> +		run_command("swapoff", FILE_SWAP_PATH, NULL);
> +		SAFE_CLOSE(fd_swapfile);
> +	}
> +	if (fd_dup > 0)
> +		SAFE_CLOSE(fd_dup);
> +	if (fd_copy > 0)
> +		SAFE_CLOSE(fd_copy);
> +	SAFE_UNLINK(FILE_FIFO);
>  }
>  
>  static void setup(void)
>  {
>  	syscall_info();
> +	char dev_path[1024];
>  
>  	if (access(FILE_DIR_PATH, F_OK) == -1)
>  		SAFE_MKDIR(FILE_DIR_PATH, 0777);
> +	/*
> +	 * call tst_find_free_loopdev(), avoid overwriting its
> +	 * content on used loopdev.
> +	 */
> +	loop_devn = tst_find_free_loopdev(dev_path, sizeof(dev_path));
> +
> +	SAFE_MKNOD(FILE_FIFO, S_IFIFO | 0777, 0);
>  
>  	fd_src    = SAFE_OPEN(FILE_SRC_PATH, O_RDWR | O_CREAT, 0664);
>  	fd_dest   = SAFE_OPEN(FILE_DEST_PATH, O_RDWR | O_CREAT, 0664);
>  	fd_rdonly = SAFE_OPEN(FILE_RDONL_PATH, O_RDONLY | O_CREAT, 0664);
> -	fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
>  	fd_dir    = SAFE_OPEN(FILE_DIR_PATH, O_DIRECTORY);
>  	fd_closed = -1;
>  	fd_append = SAFE_OPEN(FILE_DEST_PATH,
>  			O_RDWR | O_CREAT | O_APPEND, 0664);
> +	fd_immutable = SAFE_OPEN(FILE_IMMUTABLE_PATH, O_RDWR | O_CREAT, 0664);
> +	fd_swapfile = SAFE_OPEN(FILE_SWAP_PATH, O_RDWR | O_CREAT, 0600);
> +
> +	if (loop_devn == -1)
> +		fd_blkdev = SAFE_OPEN(dev_path, O_RDWR, 0600);
> +
> +	fd_chrdev = SAFE_OPEN(FILE_CHRDEV, O_RDWR, 0600);
> +	fd_fifo = SAFE_OPEN(FILE_FIFO, O_RDWR, 0600);
> +
> +	SAFE_WRITE(1, fd_src, CONTENT, CONTSIZE);
> +	close(fd_src);
> +	fd_src = SAFE_OPEN(FILE_SRC_PATH, O_RDONLY, 0664);
> +	fd_dup = SAFE_OPEN(FILE_SRC_PATH, O_WRONLY|O_CREAT, 0666);
> +
> +	fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
> +	chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> +
> +	if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
> +		tst_res(TCONF, "Insufficient disk space to create swap file");
> +		swap_nsup = 3;
> +		return;
> +	}
> +
> +	if (tst_fill_file(FILE_SWAP_PATH, 0, sysconf(_SC_PAGESIZE), 10) != 0) {
> +		tst_res(TCONF, "Failed to create swapfile");
> +		swap_nsup = 4;
> +		return;
> +	}
>  
> -	SAFE_WRITE(1, fd_src,  CONTENT,  CONTSIZE);
> +	swap_nsup = run_command("mkswap", FILE_SWAP_PATH, NULL);
> +	swap_nsup = run_command("swapon", FILE_SWAP_PATH, NULL);
>  }
>  
>  static struct tst_test test = {
> @@ -113,6 +218,6 @@ static struct tst_test test = {
>  	.needs_root = 1,
>  	.mount_device = 1,
>  	.mntpoint = MNTPOINT,
> -	.dev_fs_type = "ext4",
> +	.all_filesystems = 1,
>  	.test_variants = TEST_VARIANTS,
>  };
> -- 
> 2.18.1
> 
> 
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-05  6:58                                                 ` Murphy Zhou
@ 2019-08-05  7:11                                                   ` Yang Xu
  2019-08-05 10:22                                                     ` Murphy Zhou
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-08-05  7:11 UTC (permalink / raw)
  To: ltp

on 2019/08/05 14:58, Murphy Zhou  wrote:

>> + * 13) Try to copy contents to a file with target file range
>> >  + *     beyond maximum supported file size ->EFBIG
> Test 13) fails on latest Linus tree. Is there any report or working on this?
Hi Murphy

    Test 13)  passed on my system(64bit, 5.2.0+, ext4,vfat,btrfs,xfs ).
    Do you provide more infomation(filesystem, 32bit or 64bit)?

Thanks
Yang Xu

> Thanks!
> M
>




^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-05  7:11                                                   ` Yang Xu
@ 2019-08-05 10:22                                                     ` Murphy Zhou
  2019-08-05 11:01                                                       ` Yang Xu
  2019-08-06 16:27                                                       ` Petr Vorel
  0 siblings, 2 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-05 10:22 UTC (permalink / raw)
  To: ltp

On Mon, Aug 05, 2019 at 03:11:53PM +0800, Yang Xu wrote:
> on 2019/08/05 14:58, Murphy Zhou  wrote:
> 
> > > + * 13) Try to copy contents to a file with target file range
> > > >  + *     beyond maximum supported file size ->EFBIG
> > Test 13) fails on latest Linus tree. Is there any report or working on this?
> Hi Murphy
> 
>    Test 13)  passed on my system(64bit, 5.2.0+, ext4,vfat,btrfs,xfs ).
>    Do you provide more infomation(filesystem, 32bit or 64bit)?

All of them, ext234 xfs and vfat. 64bit

copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32

[root@8u ltp (master)]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --disable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC) 
[root@8u ltp (master)]# rpm -qv glibc
glibc-2.28-72.el8.x86_64
[root@8u ltp (master)]# mke2fs -V
mke2fs 1.44.6 (5-Mar-2019)
	Using EXT2FS Library version 1.44.6
[root@8u ltp (master)]# mkfs.xfs -V
mkfs.xfs version 5.2.0-rc0
[root@8u ltp (master)]# 

Looks like the copy succeeded at that offset.

Thanks,
M

> 
> Thanks
> Yang Xu
> 
> > Thanks!
> > M
> > 
> 
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-05 10:22                                                     ` Murphy Zhou
@ 2019-08-05 11:01                                                       ` Yang Xu
  2019-08-06  6:37                                                         ` Yang Xu
  2019-08-06 16:27                                                       ` Petr Vorel
  1 sibling, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-08-05 11:01 UTC (permalink / raw)
  To: ltp

on 2019/08/05 18:22, Murphy Zhou  wrote:

> All of them, ext234 xfs and vfat. 64bit
>
> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
>
> [root@8u ltp (master)]# gcc -v
> Using built-in specs.
> COLLECT_GCC=gcc
> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
> OFFLOAD_TARGET_NAMES=nvptx-none
> OFFLOAD_TARGET_DEFAULT=1
> Target: x86_64-redhat-linux
> Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla  --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --disable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
> Thread model: posix
> gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)
> [root@8u ltp (master)]# rpm -qv glibc
> glibc-2.28-72.el8.x86_64
> [root@8u ltp (master)]# mke2fs -V
> mke2fs 1.44.6 (5-Mar-2019)
> 	Using EXT2FS Library version 1.44.6
> [root@8u ltp (master)]# mkfs.xfs -V
> mkfs.xfs version 5.2.0-rc0
> [root@8u ltp (master)]#
>
> Looks like the copy succeeded at that offset.
Hi Murphy
Today, I use theLinux 5.3-rc3 ,  ext234 xfs and vfat 64bit all pass. This case use glibc and tst_syscall, they all failed?

my environment as below:
# gcc -v
gcc version 8.2.1 20180905 (8.2.1-3) (GCC)

#glibc -v
glibc-2.28-18.el8.x86_64

#mke2fs  -V
mke2fs 1.44.4 (18-Aug-2018)
         Using EXT2FS Library version 1.44.4

#mkfs.xfs -V
mkfs.xfs version 5.2.0-rc0

I will use your environment to reproduce this problem. Please wait.

Thanks
Yang Xu




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190805/69473885/attachment-0001.htm>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-05 11:01                                                       ` Yang Xu
@ 2019-08-06  6:37                                                         ` Yang Xu
  2019-08-06  9:29                                                           ` Murphy Zhou
  0 siblings, 1 reply; 86+ messages in thread
From: Yang Xu @ 2019-08-06  6:37 UTC (permalink / raw)
  To: ltp

on 2019/08/05 19:01, Yang Xu wrote:

> on 2019/08/05 18:22, Murphy Zhou  wrote:
>> All of them, ext234 xfs and vfat. 64bit
>>
>> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
>>
>> [root@8u ltp (master)]# gcc -v
>> Using built-in specs.
>> COLLECT_GCC=gcc
>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
>> OFFLOAD_TARGET_NAMES=nvptx-none
>> OFFLOAD_TARGET_DEFAULT=1
>> Target: x86_64-redhat-linux
>> Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla  --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --disable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
>> Thread model: posix
>> gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)
>> [root@8u ltp (master)]# rpm -qv glibc
>> glibc-2.28-72.el8.x86_64
>> [root@8u ltp (master)]# mke2fs -V
>> mke2fs 1.44.6 (5-Mar-2019)
>> 	Using EXT2FS Library version 1.44.6
>> [root@8u ltp (master)]# mkfs.xfs -V
>> mkfs.xfs version 5.2.0-rc0
>> [root@8u ltp (master)]#
>>
>> Looks like the copy succeeded at that offset.
> Hi Murphy
> Today, I use theLinux 5.3-rc3 ,  ext234 xfs and vfat 64bit all pass. This case use glibc and tst_syscall, they all failed?
>
> my environment as below:
> # gcc -v
> gcc version 8.2.1 20180905 (8.2.1-3) (GCC)
>
> #glibc -v
> glibc-2.28-18.el8.x86_64
>
> #mke2fs  -V
> mke2fs 1.44.4 (18-Aug-2018)
>          Using EXT2FS Library version 1.44.4
>
> #mkfs.xfs -V
> mkfs.xfs version 5.2.0-rc0
>
> I will use your environment to reproduce this problem. Please wait.
Hi Murphy

Test 13) still passes on my environment. mke2fs and mkfs.xfs version should not affetc all filesystem results, I think them can be excluded.
I update my gcc version to 8.3.1 20190507 ,glibc updates to  glibc-2.28-66.el8.x86_64(I don't have glibc-2.28-72.el8.x86_64, if you failed
on both glibc and syscall, I think this fail is no related with glibc).

Can you print more informatin when you run this case, as below:

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 26bfa008a..e4a7fd246 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -109,6 +109,8 @@ static void verify_copy_file_range(unsigned int n)
                 tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
                 return;
         }
+       if (tc->exp_err == EFBIG)
+               tst_res(TINFO, "tc->dst %ld  tc->len %ld", tc->dst, tc->len);
         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
                                 &tc->dst, tc->len, tc->flags));

copy_file_range02.c:120: PASS: copy_file_range failed as expected: EOVERFLOW
copy_file_range02.c:113: INFO: tc->dst 9223372036854710270  tc->len 65537
copy_file_range02.c:120: PASS: copy_file_range failed as expected: EFBIG



> Thanks
> Yang Xu
>
>
>



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20190806/e4a3462d/attachment-0001.htm>

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-06  6:37                                                         ` Yang Xu
@ 2019-08-06  9:29                                                           ` Murphy Zhou
  0 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-06  9:29 UTC (permalink / raw)
  To: ltp

On Tue, Aug 06, 2019 at 02:37:01PM +0800, Yang Xu wrote:
> on 2019/08/05 19:01, Yang Xu wrote:
> 
> > on 2019/08/05 18:22, Murphy Zhou  wrote:
> > > All of them, ext234 xfs and vfat. 64bit
> > > 
> > > copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
> > > 
> > > [root@8u ltp (master)]# gcc -v
> > > Using built-in specs.
> > > COLLECT_GCC=gcc
> > > COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
> > > OFFLOAD_TARGET_NAMES=nvptx-none
> > > OFFLOAD_TARGET_DEFAULT=1
> > > Target: x86_64-redhat-linux
> > > Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla  --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --disable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
> > > Thread model: posix
> > > gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)
> > > [root@8u ltp (master)]# rpm -qv glibc
> > > glibc-2.28-72.el8.x86_64
> > > [root@8u ltp (master)]# mke2fs -V
> > > mke2fs 1.44.6 (5-Mar-2019)
> > > 	Using EXT2FS Library version 1.44.6
> > > [root@8u ltp (master)]# mkfs.xfs -V
> > > mkfs.xfs version 5.2.0-rc0
> > > [root@8u ltp (master)]#
> > > 
> > > Looks like the copy succeeded at that offset.
> > Hi Murphy
> > Today, I use theLinux 5.3-rc3 ,  ext234 xfs and vfat 64bit all pass. This case use glibc and tst_syscall, they all failed?
> > 
> > my environment as below:
> > # gcc -v
> > gcc version 8.2.1 20180905 (8.2.1-3) (GCC)
> > 
> > #glibc -v
> > glibc-2.28-18.el8.x86_64
> > 
> > #mke2fs  -V
> > mke2fs 1.44.4 (18-Aug-2018)
> >          Using EXT2FS Library version 1.44.4
> > 
> > #mkfs.xfs -V
> > mkfs.xfs version 5.2.0-rc0
> > 
> > I will use your environment to reproduce this problem. Please wait.
> Hi Murphy
> 
> Test 13) still passes on my environment. mke2fs and mkfs.xfs version should not affetc all filesystem results, I think them can be excluded.
> I update my gcc version to 8.3.1 20190507 ,glibc updates to  glibc-2.28-66.el8.x86_64(I don't have glibc-2.28-72.el8.x86_64, if you failed
> on both glibc and syscall, I think this fail is no related with glibc).
> 
> Can you print more informatin when you run this case, as below:
> 
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 26bfa008a..e4a7fd246 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -109,6 +109,8 @@ static void verify_copy_file_range(unsigned int n)
>                 tst_res(TCONF, "filesystem doesn't have free loopdev, skip it");
>                 return;
>         }
> +       if (tc->exp_err == EFBIG)
> +               tst_res(TINFO, "tc->dst %ld  tc->len %ld", tc->dst, tc->len);
>         TEST(sys_copy_file_range(fd_src, 0, *tc->copy_to_fd,
>                                 &tc->dst, tc->len, tc->flags));
> 
> copy_file_range02.c:120: PASS: copy_file_range failed as expected: EOVERFLOW
> copy_file_range02.c:113: INFO: tc->dst 9223372036854710270  tc->len 65537
> copy_file_range02.c:120: PASS: copy_file_range failed as expected: EFBIG

That's odd..

copy_file_range02.c:112: INFO: 12: tc->dst 9223372036854710270, tc->len 65537
copy_file_range02.c:128: FAIL: copy_file_range returned wrong value: 32

> 
> 
> 
> > Thanks
> > Yang Xu
> > 
> > 
> > 
> 
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-05 10:22                                                     ` Murphy Zhou
  2019-08-05 11:01                                                       ` Yang Xu
@ 2019-08-06 16:27                                                       ` Petr Vorel
  2019-08-07 10:17                                                           ` Murphy Zhou
  1 sibling, 1 reply; 86+ messages in thread
From: Petr Vorel @ 2019-08-06 16:27 UTC (permalink / raw)
  To: ltp

Hi Murphy,

> On Mon, Aug 05, 2019 at 03:11:53PM +0800, Yang Xu wrote:
> > on 2019/08/05 14:58, Murphy Zhou  wrote:

> > > > + * 13) Try to copy contents to a file with target file range
> > > > >  + *     beyond maximum supported file size ->EFBIG
> > > Test 13) fails on latest Linus tree. Is there any report or working on this?
> > Hi Murphy

> >    Test 13)  passed on my system(64bit, 5.2.0+, ext4,vfat,btrfs,xfs ).
> >    Do you provide more infomation(filesystem, 32bit or 64bit)?

> All of them, ext234 xfs and vfat. 64bit
Hi, I can confirm that. Also fails on btrfs.

> copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
I got this one as well. I tested it today again with 5.3.0-rc3+ 0eb0ce0 ("Merge
tag 'spi-fix-v5.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi")
and got this error:

copy_file_range02.c:130: FAIL: copy_file_range failed unexpectedly; expected EFBIG, but got: EINVAL

But that is caused by tmpfs used as TMPDIR, going to send a patch fixing it.

Kind regards,
Petr

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-06 16:27                                                       ` Petr Vorel
@ 2019-08-07 10:17                                                           ` Murphy Zhou
  0 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-07 10:17 UTC (permalink / raw)
  To: Petr Vorel; +Cc: Murphy Zhou, Yang Xu, chrubis, ltp, linux-xfs

[-- Attachment #1: Type: text/plain, Size: 13975 bytes --]

ccing linux-xfs@vger.kernel.org

Hi,

Tracked down this to be a xfs specific issue:

If we call copy_file_range with a large offset like this:

	loff_t off = 9223372036854710270; // 2 ** 63
	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);

(test programme cfrbig.c attached)

xfs has it done successfully, while ext4 returns EFBIG.

ccing xfs folks to check that if this is expected for xfs.

We are now expecting EFBIG in copy_file_range02.c test #12.

Thanks!

Other info:

[root@8u ~]# xfs_info /test1
meta-data=/dev/pmem0             isize=512    agcount=4, agsize=327680 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=1310720, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@8u ~]# mkfs.xfs -V
mkfs.xfs version 5.2.0-rc0
[root@8u ~]# mount | grep test
/dev/pmem0 on /test1 type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
[root@8u ~]# uname -r
5.3.0-rc3-v5.3-rc3-282-g33920f1
[root@8u ~]# cp a.out /test1
[root@8u ~]# cp 1t /test1
[root@8u ~]# cd /test1
[root@8u test1]# ./a.out 1t 2t
ret 40945
[root@8u test1]# ll 1t 2t
-rw-r--r--. 1 root root               40945 Aug  7 17:35 1t
-rw-r--r--. 1 root root 9223372036854751215 Aug  7 17:35 2t
[root@8u test1]# 

On Tue, Aug 06, 2019 at 06:27:03PM +0200, Petr Vorel wrote:
> Hi Murphy,
> 
> > On Mon, Aug 05, 2019 at 03:11:53PM +0800, Yang Xu wrote:
> > > on 2019/08/05 14:58, Murphy Zhou  wrote:
> 
> > > > > + * 13) Try to copy contents to a file with target file range
> > > > > >  + *     beyond maximum supported file size ->EFBIG
> > > > Test 13) fails on latest Linus tree. Is there any report or working on this?
> > > Hi Murphy
> 
> > >    Test 13)  passed on my system(64bit, 5.2.0+, ext4,vfat,btrfs,xfs ).
> > >    Do you provide more infomation(filesystem, 32bit or 64bit)?
> 
> > All of them, ext234 xfs and vfat. 64bit
> Hi, I can confirm that. Also fails on btrfs.
> 
> > copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
> I got this one as well. I tested it today again with 5.3.0-rc3+ 0eb0ce0 ("Merge
> tag 'spi-fix-v5.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi")
> and got this error:
> 
> copy_file_range02.c:130: FAIL: copy_file_range failed unexpectedly; expected EFBIG, but got: EINVAL
> 
> But that is caused by tmpfs used as TMPDIR, going to send a patch fixing it.

And I have a question about LTP itself.

If we run the testcase directly like:
	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02

to test all_filesystems, for every filesystem, we mkfs and mount it in
.mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
the same tmpdir, fs type of which does not change while looping
all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
each loop.

Now we are using this to test cross-device copy in copy_file_range01.c,
but in copy_file_range02.c, we are not using .mntpint at all, all the
tests in the all_filesystems loop are running in the same tmpdir. In other
words, we are NOT testing all filesystems.

Is this expected?

I commented out testcases in copy_file_range02.c other then #12, and add
some nasty debug info:

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 56797f639..c74f1a7ec 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -62,6 +62,7 @@ static struct tcase {
 	loff_t     len;
 	const char *tname;
 } tcases[] = {
+#if 0
 	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE, "readonly file"},
 	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE, "directory"},
 	{&fd_append,	0,   EBADF,      0,     CONTSIZE, "append to file"},
@@ -74,6 +75,7 @@ static struct tcase {
 	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE, "charr device"},
 	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE, "fifo"},
 	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX, "max length lenght"},
+#endif
 	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF, "max file size"},
 };
 
@@ -163,6 +165,9 @@ static void setup(void)
 	syscall_info();
 	char dev_path[1024];
 
+	system("pwd");
+	system("df -Th .");
+	system("mount | grep loop");
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 	/*


Got this: (deleted some irrelevant lines of output)

All tests on / filesystem.


tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext2 (rw,relatime,seclabel,errors=continue,user_xattr,acl)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=faff58f0-a824-48b6-a103-bc6b1cc99a17
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext3 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=c9e759f6-866d-421d-8322-1a60e7e387ce
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext4 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=de87413e-3700-4928-9529-7968a6753dda
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=bd59eb67-2ca9-44c5-9f04-1a2bd85ef3cc
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=e29211e3-175e-46de-b8bc-e6f021de585e
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32



After adding chdir to .mntpoint in setup:


diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 56797f639..d7b0a7cfd 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -62,6 +62,7 @@ static struct tcase {
 	loff_t     len;
 	const char *tname;
 } tcases[] = {
+#if 0
 	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE, "readonly file"},
 	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE, "directory"},
 	{&fd_append,	0,   EBADF,      0,     CONTSIZE, "append to file"},
@@ -74,6 +75,7 @@ static struct tcase {
 	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE, "charr device"},
 	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE, "fifo"},
 	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX, "max length lenght"},
+#endif
 	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF, "max file size"},
 };
 
@@ -156,6 +158,7 @@ static void cleanup(void)
 	if (fd_copy > 0)
 		SAFE_CLOSE(fd_copy);
 	SAFE_UNLINK(FILE_FIFO);
+	SAFE_CHDIR("..");
 }
 
 static void setup(void)
@@ -163,6 +166,11 @@ static void setup(void)
 	syscall_info();
 	char dev_path[1024];
 
+	SAFE_CHDIR(MNTPOINT);
+
+	system("pwd");
+	system("df -Th .");
+	system("mount | grep loop");
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 	/*


Only xfs fails the test now:  (vfat brok)

tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext2  248M  2.1M  234M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext2 (rw,relatime,seclabel,errors=continue,user_xattr,acl)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=46d54fae-85fb-4836-ab69-2ebb23d8fa75
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext3  240M  2.1M  226M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext3 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=9598e117-03cc-4bf3-9706-3f072303709b
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext4  240M  2.1M  222M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext4 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=714961f8-dcda-451e-98df-091d2b670a97
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     xfs   251M   15M  236M   6% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=5a4b2adb-5b03-484c-a5b3-6e23ea3d80c8
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     vfat  256M     0  256M   0% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
safe_macros.c:1032: BROK: copy_file_range02.c:182: mknod() failed: EPERM
safe_macros.c:360: WARN: copy_file_range02.c:160: unlink(file_fifo) failed: ENOENT


Thanks!
M

> 
> Kind regards,
> Petr

[-- Attachment #2: cfrbig.c --]
[-- Type: text/plain, Size: 1077 bytes --]

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <limits.h>

#if 0
static loff_t copy_file_range(int fd_in, loff_t *off_in, int fd_out,
		        loff_t *off_out, size_t len, unsigned int flags)
{
	return syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
		           off_out, len, flags);
}
#endif

int main(int argc, char **argv)
{
	int fd_in, fd_out, ret;
	loff_t off = 9223372036854710270; // 2 ** 63

	if (argc != 3) {
		fprintf(stderr, "Usage: %s <source> <destination>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	fd_in = open(argv[1], O_RDONLY);
	if (fd_in == -1) {
		perror("open (argv[1])");
		exit(EXIT_FAILURE);
	}

	fd_out = open(argv[2], O_CREAT | O_RDWR | O_TRUNC, 0644);
	if (fd_out == -1) {
		perror("open (argv[2])");
		exit(EXIT_FAILURE);
	}

	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);
	if (ret == -1) {
		perror("copy_file_range");
		exit(EXIT_FAILURE);
	}
	printf("ret %d\n", ret);
	close(fd_in);
	close(fd_out);

	exit(EXIT_SUCCESS);
}

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-07 10:17                                                           ` Murphy Zhou
  0 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-07 10:17 UTC (permalink / raw)
  To: ltp

ccing linux-xfs@vger.kernel.org

Hi,

Tracked down this to be a xfs specific issue:

If we call copy_file_range with a large offset like this:

	loff_t off = 9223372036854710270; // 2 ** 63
	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);

(test programme cfrbig.c attached)

xfs has it done successfully, while ext4 returns EFBIG.

ccing xfs folks to check that if this is expected for xfs.

We are now expecting EFBIG in copy_file_range02.c test #12.

Thanks!

Other info:

[root@8u ~]# xfs_info /test1
meta-data=/dev/pmem0             isize=512    agcount=4, agsize=327680 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=1310720, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@8u ~]# mkfs.xfs -V
mkfs.xfs version 5.2.0-rc0
[root@8u ~]# mount | grep test
/dev/pmem0 on /test1 type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
[root@8u ~]# uname -r
5.3.0-rc3-v5.3-rc3-282-g33920f1
[root@8u ~]# cp a.out /test1
[root@8u ~]# cp 1t /test1
[root@8u ~]# cd /test1
[root@8u test1]# ./a.out 1t 2t
ret 40945
[root@8u test1]# ll 1t 2t
-rw-r--r--. 1 root root               40945 Aug  7 17:35 1t
-rw-r--r--. 1 root root 9223372036854751215 Aug  7 17:35 2t
[root@8u test1]# 

On Tue, Aug 06, 2019 at 06:27:03PM +0200, Petr Vorel wrote:
> Hi Murphy,
> 
> > On Mon, Aug 05, 2019 at 03:11:53PM +0800, Yang Xu wrote:
> > > on 2019/08/05 14:58, Murphy Zhou  wrote:
> 
> > > > > + * 13) Try to copy contents to a file with target file range
> > > > > >  + *     beyond maximum supported file size ->EFBIG
> > > > Test 13) fails on latest Linus tree. Is there any report or working on this?
> > > Hi Murphy
> 
> > >    Test 13)  passed on my system(64bit, 5.2.0+, ext4,vfat,btrfs,xfs ).
> > >    Do you provide more infomation(filesystem, 32bit or 64bit)?
> 
> > All of them, ext234 xfs and vfat. 64bit
> Hi, I can confirm that. Also fails on btrfs.
> 
> > copy_file_range02.c:127: FAIL: copy_file_range returned wrong value: 32
> I got this one as well. I tested it today again with 5.3.0-rc3+ 0eb0ce0 ("Merge
> tag 'spi-fix-v5.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi")
> and got this error:
> 
> copy_file_range02.c:130: FAIL: copy_file_range failed unexpectedly; expected EFBIG, but got: EINVAL
> 
> But that is caused by tmpfs used as TMPDIR, going to send a patch fixing it.

And I have a question about LTP itself.

If we run the testcase directly like:
	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02

to test all_filesystems, for every filesystem, we mkfs and mount it in
.mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
the same tmpdir, fs type of which does not change while looping
all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
each loop.

Now we are using this to test cross-device copy in copy_file_range01.c,
but in copy_file_range02.c, we are not using .mntpint at all, all the
tests in the all_filesystems loop are running in the same tmpdir. In other
words, we are NOT testing all filesystems.

Is this expected?

I commented out testcases in copy_file_range02.c other then #12, and add
some nasty debug info:

diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 56797f639..c74f1a7ec 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -62,6 +62,7 @@ static struct tcase {
 	loff_t     len;
 	const char *tname;
 } tcases[] = {
+#if 0
 	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE, "readonly file"},
 	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE, "directory"},
 	{&fd_append,	0,   EBADF,      0,     CONTSIZE, "append to file"},
@@ -74,6 +75,7 @@ static struct tcase {
 	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE, "charr device"},
 	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE, "fifo"},
 	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX, "max length lenght"},
+#endif
 	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF, "max file size"},
 };
 
@@ -163,6 +165,9 @@ static void setup(void)
 	syscall_info();
 	char dev_path[1024];
 
+	system("pwd");
+	system("df -Th .");
+	system("mount | grep loop");
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 	/*


Got this: (deleted some irrelevant lines of output)

All tests on / filesystem.


tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext2 (rw,relatime,seclabel,errors=continue,user_xattr,acl)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=faff58f0-a824-48b6-a103-bc6b1cc99a17
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext3 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=c9e759f6-866d-421d-8322-1a60e7e387ce
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type ext4 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=de87413e-3700-4928-9529-7968a6753dda
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=bd59eb67-2ca9-44c5-9f04-1a2bd85ef3cc
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:44: INFO: Testing __NR_copy_file_range syscall
/tmp/koASqI
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      xfs   618G  432G  187G  70% /
/dev/loop0 on /tmp/koASqI/mnt_point type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=e29211e3-175e-46de-b8bc-e6f021de585e
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32



After adding chdir to .mntpoint in setup:


diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 56797f639..d7b0a7cfd 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -62,6 +62,7 @@ static struct tcase {
 	loff_t     len;
 	const char *tname;
 } tcases[] = {
+#if 0
 	{&fd_rdonly,	0,   EBADF,      0,     CONTSIZE, "readonly file"},
 	{&fd_dir,	0,   EISDIR,     0,     CONTSIZE, "directory"},
 	{&fd_append,	0,   EBADF,      0,     CONTSIZE, "append to file"},
@@ -74,6 +75,7 @@ static struct tcase {
 	{&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE, "charr device"},
 	{&fd_fifo,      0,   EINVAL,     0,     CONTSIZE, "fifo"},
 	{&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX, "max length lenght"},
+#endif
 	{&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF, "max file size"},
 };
 
@@ -156,6 +158,7 @@ static void cleanup(void)
 	if (fd_copy > 0)
 		SAFE_CLOSE(fd_copy);
 	SAFE_UNLINK(FILE_FIFO);
+	SAFE_CHDIR("..");
 }
 
 static void setup(void)
@@ -163,6 +166,11 @@ static void setup(void)
 	syscall_info();
 	char dev_path[1024];
 
+	SAFE_CHDIR(MNTPOINT);
+
+	system("pwd");
+	system("df -Th .");
+	system("mount | grep loop");
 	if (access(FILE_DIR_PATH, F_OK) == -1)
 		SAFE_MKDIR(FILE_DIR_PATH, 0777);
 	/*


Only xfs fails the test now:  (vfat brok)

tst_test.c:1161: INFO: Testing on ext2
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext2  248M  2.1M  234M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext2 (rw,relatime,seclabel,errors=continue,user_xattr,acl)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=46d54fae-85fb-4836-ab69-2ebb23d8fa75
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on ext3
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext3  240M  2.1M  226M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext3 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=9598e117-03cc-4bf3-9706-3f072303709b
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on ext4
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts=''
mke2fs 1.44.6 (5-Mar-2019)
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext4  240M  2.1M  222M   1% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type ext4 (rw,relatime,seclabel)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=714961f8-dcda-451e-98df-091d2b670a97
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:123: PASS: copy_file_range failed as expected: EFBIG

tst_test.c:1161: INFO: Testing on xfs
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with xfs opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     xfs   251M   15M  236M   6% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
Setting up swapspace version 1, size = 36 KiB (36864 bytes)
no label, UUID=5a4b2adb-5b03-484c-a5b3-6e23ea3d80c8
copy_file_range02.c:103: INFO: Test #0: max file size
copy_file_range02.c:132: FAIL: copy_file_range returned wrong value: 32

tst_test.c:1161: INFO: Testing on vfat
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
tst_test.c:1100: INFO: Timeout per run is 0h 05m 00s
copy_file_range.h:41: INFO: Testing libc copy_file_range()
/tmp/QtMvgB/mnt_point
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     vfat  256M     0  256M   0% /tmp/QtMvgB/mnt_point
/dev/loop0 on /tmp/QtMvgB/mnt_point type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
tst_device.c:87: INFO: Found free device 1 '/dev/loop1'
safe_macros.c:1032: BROK: copy_file_range02.c:182: mknod() failed: EPERM
safe_macros.c:360: WARN: copy_file_range02.c:160: unlink(file_fifo) failed: ENOENT


Thanks!
M

> 
> Kind regards,
> Petr
-------------- next part --------------
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <limits.h>

#if 0
static loff_t copy_file_range(int fd_in, loff_t *off_in, int fd_out,
		        loff_t *off_out, size_t len, unsigned int flags)
{
	return syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
		           off_out, len, flags);
}
#endif

int main(int argc, char **argv)
{
	int fd_in, fd_out, ret;
	loff_t off = 9223372036854710270; // 2 ** 63

	if (argc != 3) {
		fprintf(stderr, "Usage: %s <source> <destination>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	fd_in = open(argv[1], O_RDONLY);
	if (fd_in == -1) {
		perror("open (argv[1])");
		exit(EXIT_FAILURE);
	}

	fd_out = open(argv[2], O_CREAT | O_RDWR | O_TRUNC, 0644);
	if (fd_out == -1) {
		perror("open (argv[2])");
		exit(EXIT_FAILURE);
	}

	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);
	if (ret == -1) {
		perror("copy_file_range");
		exit(EXIT_FAILURE);
	}
	printf("ret %d\n", ret);
	close(fd_in);
	close(fd_out);

	exit(EXIT_SUCCESS);
}

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-07 10:17                                                           ` Murphy Zhou
@ 2019-08-07 12:12                                                             ` Dave Chinner
  -1 siblings, 0 replies; 86+ messages in thread
From: Dave Chinner @ 2019-08-07 12:12 UTC (permalink / raw)
  To: Murphy Zhou; +Cc: Petr Vorel, Yang Xu, chrubis, ltp, linux-xfs

On Wed, Aug 07, 2019 at 06:17:42PM +0800, Murphy Zhou wrote:
> ccing linux-xfs@vger.kernel.org
> 
> Hi,
> 
> Tracked down this to be a xfs specific issue:
> 
> If we call copy_file_range with a large offset like this:
> 
> 	loff_t off = 9223372036854710270; // 2 ** 63
> 	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);

That's not 2**63:

$ echo $((9223372036854710270 + 65537))
9223372036854775807

$ echo $((2**63 - 1))
9223372036854775807

i.e. it's LLONG_MAX, not an overflow. XFS sets sb->s_maxbytes in
xfs_max_file_offset to:

	(1 << BITS_PER_LONG - 1) - 1 = 2**63 - 1 = LLONG_MAX.

So no matter how we look at it, this operation should not return
EFBIG on XFS.

> (test programme cfrbig.c attached)
> 
> xfs has it done successfully, while ext4 returns EFBIG.

ext4 has a max file size of 2**32 * blocksize, so it doesn't support
files larger than 16TB. So it will give EFBIG on this test.

/me compiles and runs the test program on his workstation:

$ ls -l foobar
-rw------- 1 dave dave 10737418240 Apr 12 14:46 foobar
$ ./a.out foobar bar
ret 65537
$ ls -l bar
-rw-r--r-- 1 dave dave 9223372036854775807 Aug  7 22:11 bar
$

That looks like a successful copy to me, not EINVAL or EFBIG...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-07 12:12                                                             ` Dave Chinner
  0 siblings, 0 replies; 86+ messages in thread
From: Dave Chinner @ 2019-08-07 12:12 UTC (permalink / raw)
  To: ltp

On Wed, Aug 07, 2019 at 06:17:42PM +0800, Murphy Zhou wrote:
> ccing linux-xfs@vger.kernel.org
> 
> Hi,
> 
> Tracked down this to be a xfs specific issue:
> 
> If we call copy_file_range with a large offset like this:
> 
> 	loff_t off = 9223372036854710270; // 2 ** 63
> 	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);

That's not 2**63:

$ echo $((9223372036854710270 + 65537))
9223372036854775807

$ echo $((2**63 - 1))
9223372036854775807

i.e. it's LLONG_MAX, not an overflow. XFS sets sb->s_maxbytes in
xfs_max_file_offset to:

	(1 << BITS_PER_LONG - 1) - 1 = 2**63 - 1 = LLONG_MAX.

So no matter how we look@it, this operation should not return
EFBIG on XFS.

> (test programme cfrbig.c attached)
> 
> xfs has it done successfully, while ext4 returns EFBIG.

ext4 has a max file size of 2**32 * blocksize, so it doesn't support
files larger than 16TB. So it will give EFBIG on this test.

/me compiles and runs the test program on his workstation:

$ ls -l foobar
-rw------- 1 dave dave 10737418240 Apr 12 14:46 foobar
$ ./a.out foobar bar
ret 65537
$ ls -l bar
-rw-r--r-- 1 dave dave 9223372036854775807 Aug  7 22:11 bar
$

That looks like a successful copy to me, not EINVAL or EFBIG...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-08  3:11                                                             ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-08-08  3:11 UTC (permalink / raw)
  To: Murphy Zhou; +Cc: Petr Vorel, chrubis, ltp, linux-xfs

on 2019/08/07 18:17, Murphy Zhou wrote:

> And I have a question about LTP itself.
>
> If we run the testcase directly like:
> 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02
>
> to test all_filesystems, for every filesystem, we mkfs and mount it in
> .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> the same tmpdir, fs type of which does not change while looping
> all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> each loop.
>
> Now we are using this to test cross-device copy in copy_file_range01.c,
> but in copy_file_range02.c, we are not using .mntpint at all, all the
> tests in the all_filesystems loop are running in the same tmpdir. In other
> words, we are NOT testing all filesystems.
>
> Is this expected?
 I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

as below:
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 26bfa008a..67974ffa2 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -49,6 +49,7 @@ static int fd_blkdev;
 static int fd_chrdev;
 static int fd_fifo;
 static int fd_copy;
+static int fd_mnted;

 static int chattr_i_nsup;
 static int swap_nsup;

@@ -73,7 +74,7 @@ static struct tcase {
        {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
        {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
        {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
-       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
+       {&fd_mnted,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };

 static int run_command(char *command, char *option, char *file)
@@ -117,7 +118,10 @@ static void verify_copy_file_range(unsigned int n)
                        tst_res(TPASS | TTERRNO,
                                        "copy_file_range failed as expected");
                } else {
-                       tst_res(TFAIL | TTERRNO,
+                       if (tc->exp_err == EFBIG && TST_ERR == EXDEV)
+                               tst_res(TCONF, "copy_file_range doesn't support cross-device,skip it");
+                       else
+                               tst_res(TFAIL | TTERRNO,
                                "copy_file_range failed unexpectedly; expected %s, but got",
                                tst_strerrno(tc->exp_err));
                        return;

@@ -152,6 +156,8 @@ static void cleanup(void)
                SAFE_CLOSE(fd_dup);
        if (fd_copy > 0)
                SAFE_CLOSE(fd_copy);
+       if (fd_mnted > 0)
+               SAFE_CLOSE(fd_mnted);
        SAFE_UNLINK(FILE_FIFO);
 }

@@ -194,6 +200,7 @@ static void setup(void)

        fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
        chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);

        if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
                tst_res(TCONF, "Insufficient disk space to create swap file");
                swap_nsup = 3;

test12) succeed on extN, failed on both btrfs and xfs, we need to detect filesystem type to handle. Or, I think we 
can set a limit on filesize because this kind of user scene is a bit more than the first one , the EFBIG error can be 
received easily (Also, we don't need  mnt_device mntpoint all_filesystem if so).
What do you think about it?

> I commented out testcases in copy_file_range02.c other then #12, and add
> some nasty debug info:

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-08  3:11                                                             ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-08-08  3:11 UTC (permalink / raw)
  To: Murphy Zhou; +Cc: Petr Vorel, chrubis, ltp, linux-xfs

on 2019/08/07 18:17, Murphy Zhou wrote:

> And I have a question about LTP itself.
>
> If we run the testcase directly like:
> 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02
>
> to test all_filesystems, for every filesystem, we mkfs and mount it in
> .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> the same tmpdir, fs type of which does not change while looping
> all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> each loop.
>
> Now we are using this to test cross-device copy in copy_file_range01.c,
> but in copy_file_range02.c, we are not using .mntpint at all, all the
> tests in the all_filesystems loop are running in the same tmpdir. In other
> words, we are NOT testing all filesystems.
>
> Is this expected?
 I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

as below:
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 26bfa008a..67974ffa2 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -49,6 +49,7 @@ static int fd_blkdev;
 static int fd_chrdev;
 static int fd_fifo;
 static int fd_copy;
+static int fd_mnted;

 static int chattr_i_nsup;
 static int swap_nsup;

@@ -73,7 +74,7 @@ static struct tcase {
        {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
        {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
        {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
-       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
+       {&fd_mnted,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };

 static int run_command(char *command, char *option, char *file)
@@ -117,7 +118,10 @@ static void verify_copy_file_range(unsigned int n)
                        tst_res(TPASS | TTERRNO,
                                        "copy_file_range failed as expected");
                } else {
-                       tst_res(TFAIL | TTERRNO,
+                       if (tc->exp_err == EFBIG && TST_ERR == EXDEV)
+                               tst_res(TCONF, "copy_file_range doesn't support cross-device,skip it");
+                       else
+                               tst_res(TFAIL | TTERRNO,
                                "copy_file_range failed unexpectedly; expected %s, but got",
                                tst_strerrno(tc->exp_err));
                        return;

@@ -152,6 +156,8 @@ static void cleanup(void)
                SAFE_CLOSE(fd_dup);
        if (fd_copy > 0)
                SAFE_CLOSE(fd_copy);
+       if (fd_mnted > 0)
+               SAFE_CLOSE(fd_mnted);
        SAFE_UNLINK(FILE_FIFO);
 }

@@ -194,6 +200,7 @@ static void setup(void)

        fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
        chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);

        if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
                tst_res(TCONF, "Insufficient disk space to create swap file");
                swap_nsup = 3;

test12) succeed on extN, failed on both btrfs and xfs, we need to detect filesystem type to handle. Or, I think we 
can set a limit on filesize because this kind of user scene is a bit more than the first one , the EFBIG error can be 
received easily (Also, we don't need  mnt_device mntpoint all_filesystem if so).
What do you think about it?

> I commented out testcases in copy_file_range02.c other then #12, and add
> some nasty debug info:




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-08  3:11                                                             ` Yang Xu
  0 siblings, 0 replies; 86+ messages in thread
From: Yang Xu @ 2019-08-08  3:11 UTC (permalink / raw)
  To: ltp

on 2019/08/07 18:17, Murphy Zhou wrote:

> And I have a question about LTP itself.
>
> If we run the testcase directly like:
> 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02
>
> to test all_filesystems, for every filesystem, we mkfs and mount it in
> .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> the same tmpdir, fs type of which does not change while looping
> all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> each loop.
>
> Now we are using this to test cross-device copy in copy_file_range01.c,
> but in copy_file_range02.c, we are not using .mntpint at all, all the
> tests in the all_filesystems loop are running in the same tmpdir. In other
> words, we are NOT testing all filesystems.
>
> Is this expected?
 I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

as below:
diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
index 26bfa008a..67974ffa2 100644
--- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
+++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
@@ -49,6 +49,7 @@ static int fd_blkdev;
 static int fd_chrdev;
 static int fd_fifo;
 static int fd_copy;
+static int fd_mnted;

 static int chattr_i_nsup;
 static int swap_nsup;

@@ -73,7 +74,7 @@ static struct tcase {
        {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
        {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
        {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
-       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
+       {&fd_mnted,      0,   EFBIG,      MAX_OFF, MIN_OFF},
 };

 static int run_command(char *command, char *option, char *file)
@@ -117,7 +118,10 @@ static void verify_copy_file_range(unsigned int n)
                        tst_res(TPASS | TTERRNO,
                                        "copy_file_range failed as expected");
                } else {
-                       tst_res(TFAIL | TTERRNO,
+                       if (tc->exp_err == EFBIG && TST_ERR == EXDEV)
+                               tst_res(TCONF, "copy_file_range doesn't support cross-device,skip it");
+                       else
+                               tst_res(TFAIL | TTERRNO,
                                "copy_file_range failed unexpectedly; expected %s, but got",
                                tst_strerrno(tc->exp_err));
                        return;

@@ -152,6 +156,8 @@ static void cleanup(void)
                SAFE_CLOSE(fd_dup);
        if (fd_copy > 0)
                SAFE_CLOSE(fd_copy);
+       if (fd_mnted > 0)
+               SAFE_CLOSE(fd_mnted);
        SAFE_UNLINK(FILE_FIFO);
 }

@@ -194,6 +200,7 @@ static void setup(void)

        fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
        chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
+       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);

        if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
                tst_res(TCONF, "Insufficient disk space to create swap file");
                swap_nsup = 3;

test12) succeed on extN, failed on both btrfs and xfs, we need to detect filesystem type to handle. Or, I think we 
can set a limit on filesize because this kind of user scene is a bit more than the first one , the EFBIG error can be 
received easily (Also, we don't need  mnt_device mntpoint all_filesystem if so).
What do you think about it?

> I commented out testcases in copy_file_range02.c other then #12, and add
> some nasty debug info:




^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-07 12:12                                                             ` Dave Chinner
@ 2019-08-08  3:46                                                               ` Murphy Zhou
  -1 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-08  3:46 UTC (permalink / raw)
  To: Dave Chinner; +Cc: Murphy Zhou, Petr Vorel, Yang Xu, chrubis, ltp, linux-xfs

On Wed, Aug 07, 2019 at 10:12:12PM +1000, Dave Chinner wrote:
> On Wed, Aug 07, 2019 at 06:17:42PM +0800, Murphy Zhou wrote:
> > ccing linux-xfs@vger.kernel.org
> > 
> > Hi,
> > 
> > Tracked down this to be a xfs specific issue:
> > 
> > If we call copy_file_range with a large offset like this:
> > 
> > 	loff_t off = 9223372036854710270; // 2 ** 63
> > 	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);
> 
> That's not 2**63:

Ya! I was looking too roughly.

> 
> $ echo $((9223372036854710270 + 65537))
> 9223372036854775807
> 
> $ echo $((2**63 - 1))
> 9223372036854775807
> 
> i.e. it's LLONG_MAX, not an overflow. XFS sets sb->s_maxbytes in
> xfs_max_file_offset to:
> 
> 	(1 << BITS_PER_LONG - 1) - 1 = 2**63 - 1 = LLONG_MAX.
> 
> So no matter how we look at it, this operation should not return
> EFBIG on XFS.
> 
> > (test programme cfrbig.c attached)
> > 
> > xfs has it done successfully, while ext4 returns EFBIG.
> 
> ext4 has a max file size of 2**32 * blocksize, so it doesn't support
> files larger than 16TB. So it will give EFBIG on this test.
> 
> /me compiles and runs the test program on his workstation:
> 
> $ ls -l foobar
> -rw------- 1 dave dave 10737418240 Apr 12 14:46 foobar
> $ ./a.out foobar bar
> ret 65537
> $ ls -l bar
> -rw-r--r-- 1 dave dave 9223372036854775807 Aug  7 22:11 bar
> $
> 
> That looks like a successful copy to me, not EINVAL or EFBIG...

Thanks Dave for the confirmation! This testcase needs some fix.

Murphy

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-08  3:46                                                               ` Murphy Zhou
  0 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-08  3:46 UTC (permalink / raw)
  To: ltp

On Wed, Aug 07, 2019 at 10:12:12PM +1000, Dave Chinner wrote:
> On Wed, Aug 07, 2019 at 06:17:42PM +0800, Murphy Zhou wrote:
> > ccing linux-xfs@vger.kernel.org
> > 
> > Hi,
> > 
> > Tracked down this to be a xfs specific issue:
> > 
> > If we call copy_file_range with a large offset like this:
> > 
> > 	loff_t off = 9223372036854710270; // 2 ** 63
> > 	ret = copy_file_range(fd_in, 0, fd_out, &off, 65537, 0);
> 
> That's not 2**63:

Ya! I was looking too roughly.

> 
> $ echo $((9223372036854710270 + 65537))
> 9223372036854775807
> 
> $ echo $((2**63 - 1))
> 9223372036854775807
> 
> i.e. it's LLONG_MAX, not an overflow. XFS sets sb->s_maxbytes in
> xfs_max_file_offset to:
> 
> 	(1 << BITS_PER_LONG - 1) - 1 = 2**63 - 1 = LLONG_MAX.
> 
> So no matter how we look at it, this operation should not return
> EFBIG on XFS.
> 
> > (test programme cfrbig.c attached)
> > 
> > xfs has it done successfully, while ext4 returns EFBIG.
> 
> ext4 has a max file size of 2**32 * blocksize, so it doesn't support
> files larger than 16TB. So it will give EFBIG on this test.
> 
> /me compiles and runs the test program on his workstation:
> 
> $ ls -l foobar
> -rw------- 1 dave dave 10737418240 Apr 12 14:46 foobar
> $ ./a.out foobar bar
> ret 65537
> $ ls -l bar
> -rw-r--r-- 1 dave dave 9223372036854775807 Aug  7 22:11 bar
> $
> 
> That looks like a successful copy to me, not EINVAL or EFBIG...

Thanks Dave for the confirmation! This testcase needs some fix.

Murphy

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-08  3:11                                                             ` Yang Xu
@ 2019-08-08  3:57                                                               ` Murphy Zhou
  -1 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-08  3:57 UTC (permalink / raw)
  To: Yang Xu; +Cc: Murphy Zhou, Petr Vorel, chrubis, ltp, linux-xfs

On Thu, Aug 08, 2019 at 11:11:43AM +0800, Yang Xu wrote:
> on 2019/08/07 18:17, Murphy Zhou wrote:
> 
> > And I have a question about LTP itself.
> >
> > If we run the testcase directly like:
> > 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02
> >
> > to test all_filesystems, for every filesystem, we mkfs and mount it in
> > .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> > the same tmpdir, fs type of which does not change while looping
> > all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> > each loop.
> >
> > Now we are using this to test cross-device copy in copy_file_range01.c,
> > but in copy_file_range02.c, we are not using .mntpint at all, all the
> > tests in the all_filesystems loop are running in the same tmpdir. In other
> > words, we are NOT testing all filesystems.
> >
> > Is this expected?
>  I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
> And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

If mntpoint is not used, it makes absolutely NO sense to test all_filesystems.

Because in the all_filesystems loop, various supported filesystems are
created and mounted in mntpoint.

And the copy_file_range tests happens outside of mntpoint. It just repeats
the same test several times in the same tmpdir, fs type of which depends
on /tmp configuration.

When the log prints "testing ext2", it's not the truth.

EFBIG is another issue.

Thanks,
Murphy
> 
> as below:
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 26bfa008a..67974ffa2 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -49,6 +49,7 @@ static int fd_blkdev;
>  static int fd_chrdev;
>  static int fd_fifo;
>  static int fd_copy;
> +static int fd_mnted;
> 
>  static int chattr_i_nsup;
>  static int swap_nsup;
> 
> @@ -73,7 +74,7 @@ static struct tcase {
>         {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
>         {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
>         {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
> -       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
> +       {&fd_mnted,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
> 
>  static int run_command(char *command, char *option, char *file)
> @@ -117,7 +118,10 @@ static void verify_copy_file_range(unsigned int n)
>                         tst_res(TPASS | TTERRNO,
>                                         "copy_file_range failed as expected");
>                 } else {
> -                       tst_res(TFAIL | TTERRNO,
> +                       if (tc->exp_err == EFBIG && TST_ERR == EXDEV)
> +                               tst_res(TCONF, "copy_file_range doesn't support cross-device,skip it");
> +                       else
> +                               tst_res(TFAIL | TTERRNO,
>                                 "copy_file_range failed unexpectedly; expected %s, but got",
>                                 tst_strerrno(tc->exp_err));
>                         return;
> 
> @@ -152,6 +156,8 @@ static void cleanup(void)
>                 SAFE_CLOSE(fd_dup);
>         if (fd_copy > 0)
>                 SAFE_CLOSE(fd_copy);
> +       if (fd_mnted > 0)
> +               SAFE_CLOSE(fd_mnted);
>         SAFE_UNLINK(FILE_FIFO);
>  }
> 
> @@ -194,6 +200,7 @@ static void setup(void)
> 
>         fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
>         chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> +       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> 
>         if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
>                 tst_res(TCONF, "Insufficient disk space to create swap file");
>                 swap_nsup = 3;
> 
> test12) succeed on extN, failed on both btrfs and xfs, we need to detect filesystem type to handle. Or, I think we 
> can set a limit on filesize because this kind of user scene is a bit more than the first one , the EFBIG error can be 
> received easily (Also, we don't need  mnt_device mntpoint all_filesystem if so).
> What do you think about it?
> 
> > I commented out testcases in copy_file_range02.c other then #12, and add
> > some nasty debug info:
> 
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-08  3:57                                                               ` Murphy Zhou
  0 siblings, 0 replies; 86+ messages in thread
From: Murphy Zhou @ 2019-08-08  3:57 UTC (permalink / raw)
  To: ltp

On Thu, Aug 08, 2019 at 11:11:43AM +0800, Yang Xu wrote:
> on 2019/08/07 18:17, Murphy Zhou wrote:
> 
> > And I have a question about LTP itself.
> >
> > If we run the testcase directly like:
> > 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02
> >
> > to test all_filesystems, for every filesystem, we mkfs and mount it in
> > .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> > the same tmpdir, fs type of which does not change while looping
> > all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> > each loop.
> >
> > Now we are using this to test cross-device copy in copy_file_range01.c,
> > but in copy_file_range02.c, we are not using .mntpint at all, all the
> > tests in the all_filesystems loop are running in the same tmpdir. In other
> > words, we are NOT testing all filesystems.
> >
> > Is this expected?
>  I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
> And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

If mntpoint is not used, it makes absolutely NO sense to test all_filesystems.

Because in the all_filesystems loop, various supported filesystems are
created and mounted in mntpoint.

And the copy_file_range tests happens outside of mntpoint. It just repeats
the same test several times in the same tmpdir, fs type of which depends
on /tmp configuration.

When the log prints "testing ext2", it's not the truth.

EFBIG is another issue.

Thanks,
Murphy
> 
> as below:
> diff --git a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> index 26bfa008a..67974ffa2 100644
> --- a/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> +++ b/testcases/kernel/syscalls/copy_file_range/copy_file_range02.c
> @@ -49,6 +49,7 @@ static int fd_blkdev;
>  static int fd_chrdev;
>  static int fd_fifo;
>  static int fd_copy;
> +static int fd_mnted;
> 
>  static int chattr_i_nsup;
>  static int swap_nsup;
> 
> @@ -73,7 +74,7 @@ static struct tcase {
>         {&fd_chrdev,    0,   EINVAL,     0,     CONTSIZE},
>         {&fd_fifo,      0,   EINVAL,     0,     CONTSIZE},
>         {&fd_copy,      0,   EOVERFLOW,  MAX_OFF, ULLONG_MAX},
> -       {&fd_copy,      0,   EFBIG,      MAX_OFF, MIN_OFF},
> +       {&fd_mnted,      0,   EFBIG,      MAX_OFF, MIN_OFF},
>  };
> 
>  static int run_command(char *command, char *option, char *file)
> @@ -117,7 +118,10 @@ static void verify_copy_file_range(unsigned int n)
>                         tst_res(TPASS | TTERRNO,
>                                         "copy_file_range failed as expected");
>                 } else {
> -                       tst_res(TFAIL | TTERRNO,
> +                       if (tc->exp_err == EFBIG && TST_ERR == EXDEV)
> +                               tst_res(TCONF, "copy_file_range doesn't support cross-device,skip it");
> +                       else
> +                               tst_res(TFAIL | TTERRNO,
>                                 "copy_file_range failed unexpectedly; expected %s, but got",
>                                 tst_strerrno(tc->exp_err));
>                         return;
> 
> @@ -152,6 +156,8 @@ static void cleanup(void)
>                 SAFE_CLOSE(fd_dup);
>         if (fd_copy > 0)
>                 SAFE_CLOSE(fd_copy);
> +       if (fd_mnted > 0)
> +               SAFE_CLOSE(fd_mnted);
>         SAFE_UNLINK(FILE_FIFO);
>  }
> 
> @@ -194,6 +200,7 @@ static void setup(void)
> 
>         fd_copy = SAFE_OPEN(FILE_COPY_PATH, O_RDWR | O_CREAT | O_TRUNC, 0664);
>         chattr_i_nsup = run_command("chattr", "+i", FILE_IMMUTABLE_PATH);
> +       fd_mnted  = SAFE_OPEN(FILE_MNTED_PATH, O_RDWR | O_CREAT, 0664);
> 
>         if (!tst_fs_has_free(".", sysconf(_SC_PAGESIZE) * 10, TST_BYTES)) {
>                 tst_res(TCONF, "Insufficient disk space to create swap file");
>                 swap_nsup = 3;
> 
> test12) succeed on extN, failed on both btrfs and xfs, we need to detect filesystem type to handle. Or, I think we 
> can set a limit on filesize because this kind of user scene is a bit more than the first one , the EFBIG error can be 
> received easily (Also, we don't need  mnt_device mntpoint all_filesystem if so).
> What do you think about it?
> 
> > I commented out testcases in copy_file_range02.c other then #12, and add
> > some nasty debug info:
> 
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
  2019-08-08  3:57                                                               ` Murphy Zhou
@ 2019-08-27 10:04                                                                 ` Petr Vorel
  -1 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-08-27 10:04 UTC (permalink / raw)
  To: Murphy Zhou; +Cc: Yang Xu, chrubis, ltp, linux-xfs, Clemens Famulla-Conrad

Hi Murphy,

> On Thu, Aug 08, 2019 at 11:11:43AM +0800, Yang Xu wrote:
> > on 2019/08/07 18:17, Murphy Zhou wrote:

> > > And I have a question about LTP itself.

> > > If we run the testcase directly like:
> > > 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02

> > > to test all_filesystems, for every filesystem, we mkfs and mount it in
> > > .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> > > the same tmpdir, fs type of which does not change while looping
> > > all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> > > each loop.

> > > Now we are using this to test cross-device copy in copy_file_range01.c,
> > > but in copy_file_range02.c, we are not using .mntpint at all, all the
> > > tests in the all_filesystems loop are running in the same tmpdir. In other
> > > words, we are NOT testing all filesystems.

> > > Is this expected?
> >  I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
> > And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

> If mntpoint is not used, it makes absolutely NO sense to test all_filesystems.
Thanks for pointing this out. I was blind when reviewing this patchset.
At least this has been fixed.

> Because in the all_filesystems loop, various supported filesystems are
> created and mounted in mntpoint.

> And the copy_file_range tests happens outside of mntpoint. It just repeats
> the same test several times in the same tmpdir, fs type of which depends
> on /tmp configuration.

> When the log prints "testing ext2", it's not the truth.

> EFBIG is another issue.
Yep, we still need to think about different errnos, which depend on LTP policy
being defined [1].

> Thanks,
> Murphy

Kind regards,
Petr

[1] https://patchwork.ozlabs.org/patch/1143438/

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test
@ 2019-08-27 10:04                                                                 ` Petr Vorel
  0 siblings, 0 replies; 86+ messages in thread
From: Petr Vorel @ 2019-08-27 10:04 UTC (permalink / raw)
  To: ltp

Hi Murphy,

> On Thu, Aug 08, 2019 at 11:11:43AM +0800, Yang Xu wrote:
> > on 2019/08/07 18:17, Murphy Zhou wrote:

> > > And I have a question about LTP itself.

> > > If we run the testcase directly like:
> > > 	 ./testcases/kernel/syscalls/copy_file_range/copy_file_range02

> > > to test all_filesystems, for every filesystem, we mkfs and mount it in
> > > .mntpoint, but we do not chdir to .mntpoint. So we are running tests in 
> > > the same tmpdir, fs type of which does not change while looping
> > > all_filesystems.  Only the .mntpoint in tmpdir has different fs type in
> > > each loop.

> > > Now we are using this to test cross-device copy in copy_file_range01.c,
> > > but in copy_file_range02.c, we are not using .mntpint at all, all the
> > > tests in the all_filesystems loop are running in the same tmpdir. In other
> > > words, we are NOT testing all filesystems.

> > > Is this expected?
> >  I removed the mnted test for cross-device copy_file_range in copy_file_range02.c.
> > And I ignore the non-used mntpoint. IMO, we can directly use the FILE_MNTED to test EFBIG on all filesystems, 

> If mntpoint is not used, it makes absolutely NO sense to test all_filesystems.
Thanks for pointing this out. I was blind when reviewing this patchset.
At least this has been fixed.

> Because in the all_filesystems loop, various supported filesystems are
> created and mounted in mntpoint.

> And the copy_file_range tests happens outside of mntpoint. It just repeats
> the same test several times in the same tmpdir, fs type of which depends
> on /tmp configuration.

> When the log prints "testing ext2", it's not the truth.

> EFBIG is another issue.
Yep, we still need to think about different errnos, which depend on LTP policy
being defined [1].

> Thanks,
> Murphy

Kind regards,
Petr

[1] https://patchwork.ozlabs.org/patch/1143438/

^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2019-08-27 10:04 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-03  3:41 [LTP] [PATCH] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-05 15:22 ` Amir Goldstein
2019-07-05 20:42   ` [LTP] [PATCH v2] " Yang Xu
2019-07-08 15:17     ` Amir Goldstein
2019-07-09  6:57       ` Yang Xu
2019-07-09 10:06         ` Amir Goldstein
2019-07-10  7:18           ` [LTP] [PATCH v3 1/3] lib: alter find_free_loopdev() Yang Xu
2019-07-10  7:18             ` [LTP] [PATCH v3 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
2019-07-10  7:50               ` Amir Goldstein
2019-07-10  8:22                 ` Yang Xu
2019-07-10  7:18             ` [LTP] [PATCH v3 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-10  7:57               ` Amir Goldstein
2019-07-10  9:31                 ` Yang Xu
2019-07-10 10:53                   ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Yang Xu
2019-07-10 10:53                     ` [LTP] [PATCH v4 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
2019-07-10 15:56                       ` Xiao Yang
2019-07-11  6:18                         ` Yang Xu
2019-07-10 10:53                     ` [LTP] [PATCH v4 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-10 13:57                     ` [LTP] [PATCH v4 1/3] lib: alter find_free_loopdev() Cyril Hrubis
2019-07-11  4:00                       ` Yang Xu
2019-07-11 12:51                         ` Cyril Hrubis
2019-07-12  5:25                           ` Yang Xu
2019-07-17  5:29                             ` Yang Xu
2019-07-17  6:10                             ` Amir Goldstein
2019-07-17  9:44                           ` [LTP] [PATCH v5 " Yang Xu
2019-07-17  9:44                             ` [LTP] [PATCH v5 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
2019-07-29 13:56                               ` Petr Vorel
2019-07-29 13:59                                 ` Petr Vorel
2019-07-17  9:44                             ` [LTP] [PATCH v5 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-17 10:14                             ` [LTP] [PATCH v5 1/3] lib: alter find_free_loopdev() Amir Goldstein
2019-07-17 10:34                               ` Yang Xu
2019-07-17 10:54                                 ` Cyril Hrubis
2019-07-18  7:30                                   ` Yang Xu
2019-07-25  5:01                                     ` [LTP] [PATCH v6 " Yang Xu
2019-07-25  5:01                                       ` [LTP] [PATCH v6 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
2019-07-29 14:00                                         ` Petr Vorel
2019-07-29 14:10                                           ` Petr Vorel
2019-07-30  8:31                                             ` Yang Xu
2019-07-30 13:35                                               ` Petr Vorel
2019-07-31  7:01                                                 ` Yang Xu
2019-07-31  7:47                                                   ` Petr Vorel
2019-07-25  5:01                                       ` [LTP] [PATCH v6 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-25  5:24                                         ` Amir Goldstein
2019-07-25  5:44                                           ` Yang Xu
2019-07-25  8:08                                             ` Amir Goldstein
2019-07-25 10:13                                               ` Yang Xu
2019-07-25 11:02                                                 ` Amir Goldstein
2019-07-30 13:26                                         ` Petr Vorel
2019-07-31  7:09                                           ` Yang Xu
2019-07-29 13:01                                       ` [LTP] [PATCH v6 1/3] lib: alter find_free_loopdev() Cyril Hrubis
2019-07-30 10:42                                         ` Yang Xu
2019-07-30 11:05                                           ` Cyril Hrubis
2019-07-31 10:40                                             ` [LTP] [PATCH v7 " Yang Xu
2019-07-31 10:40                                               ` [LTP] [PATCH v7 2/3] syscalls/copy_file_range01: add cross-device test Yang Xu
2019-07-31 12:28                                                 ` Petr Vorel
2019-07-31 10:40                                               ` [LTP] [PATCH v7 3/3] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-31 12:28                                                 ` Petr Vorel
2019-08-05  6:58                                                 ` Murphy Zhou
2019-08-05  7:11                                                   ` Yang Xu
2019-08-05 10:22                                                     ` Murphy Zhou
2019-08-05 11:01                                                       ` Yang Xu
2019-08-06  6:37                                                         ` Yang Xu
2019-08-06  9:29                                                           ` Murphy Zhou
2019-08-06 16:27                                                       ` Petr Vorel
2019-08-07 10:17                                                         ` Murphy Zhou
2019-08-07 10:17                                                           ` Murphy Zhou
2019-08-07 12:12                                                           ` Dave Chinner
2019-08-07 12:12                                                             ` Dave Chinner
2019-08-08  3:46                                                             ` Murphy Zhou
2019-08-08  3:46                                                               ` Murphy Zhou
2019-08-08  3:11                                                           ` Yang Xu
2019-08-08  3:11                                                             ` Yang Xu
2019-08-08  3:11                                                             ` Yang Xu
2019-08-08  3:57                                                             ` Murphy Zhou
2019-08-08  3:57                                                               ` Murphy Zhou
2019-08-27 10:04                                                               ` Petr Vorel
2019-08-27 10:04                                                                 ` Petr Vorel
2019-07-31 12:05                                               ` [LTP] [PATCH v7 1/3] lib: alter find_free_loopdev() Petr Vorel
2019-07-31 12:28                                                 ` Cyril Hrubis
2019-07-31 12:48                                                   ` Petr Vorel
2019-07-31 13:25                                                     ` Cyril Hrubis
2019-07-31 21:06                                                       ` Petr Vorel
2019-07-31 12:07                                               ` Petr Vorel
2019-07-10  7:47             ` [LTP] [PATCH v3 " Amir Goldstein
2019-07-10  7:32           ` [LTP] [PATCH v2] syscalls/copy_file_range02: increase coverage and remove EXDEV test Yang Xu
2019-07-08 10:38   ` [LTP] [PATCH] " Yang Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.