1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019 SUSE LLC
4  * Author: Christian Amann <camann@suse.com>
5  */
6 
7 #ifndef __COPY_FILE_RANGE_H__
8 #define __COPY_FILE_RANGE_H__
9 
10 #include <stdio.h>
11 #include "lapi/syscalls.h"
12 #include "lapi/fs.h"
13 
14 #define TEST_VARIANTS	2
15 
16 #define MNTPOINT	"mnt_point"
17 #define FILE_SRC_PATH   "file_src"
18 #define FILE_DEST_PATH  "file_dest"
19 #define FILE_RDONL_PATH "file_rdonl"
20 #define FILE_DIR_PATH	"file_dir"
21 #define FILE_MNTED_PATH  MNTPOINT"/file_mnted"
22 #define FILE_IMMUTABLE_PATH "file_immutable"
23 #define FILE_SWAP_PATH "file_swap"
24 #define FILE_CHRDEV    "/dev/null"
25 #define FILE_FIFO      "file_fifo"
26 #define FILE_COPY_PATH  "file_copy"
27 
28 #define CONTENT		"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345\n"
29 #define CONTSIZE	(sizeof(CONTENT) - 1)
30 #define MIN_OFF   65537
31 
syscall_info(void)32 static void syscall_info(void)
33 {
34 	switch (tst_variant) {
35 	case 0:
36 		tst_res(TINFO, "Testing libc copy_file_range()");
37 		break;
38 	case 1:
39 		tst_res(TINFO, "Testing __NR_copy_file_range syscall");
40 	}
41 }
42 
sys_copy_file_range(int fd_in,loff_t * off_in,int fd_out,loff_t * off_out,size_t len,unsigned int flags)43 static int sys_copy_file_range(int fd_in, loff_t *off_in,
44 		int fd_out, loff_t *off_out, size_t len, unsigned int flags)
45 {
46 	switch (tst_variant) {
47 
48 	case 0:
49 #ifdef HAVE_COPY_FILE_RANGE
50 		return copy_file_range(fd_in, off_in,
51 				fd_out, off_out, len, flags);
52 #else
53 		tst_brk(TCONF, "libc copy_file_range() not supported");
54 #endif
55 		break;
56 	case 1:
57 		return tst_syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
58 				off_out, len, flags);
59 	}
60 	return -1;
61 }
62 
verify_cross_fs_copy_support(const char * path_in,const char * path_out)63 static inline int verify_cross_fs_copy_support(const char *path_in, const char *path_out)
64 {
65 	int i, fd, fd_test;
66 
67 	fd = SAFE_OPEN(path_in, O_RDWR | O_CREAT, 0664);
68 	/* Writing page_size * 4 of data into test file */
69 	for (i = 0; i < (int)(getpagesize() * 4); i++)
70 		SAFE_WRITE(1, fd, CONTENT, CONTSIZE);
71 
72 	fd_test = SAFE_OPEN(path_out, O_RDWR | O_CREAT, 0664);
73 	TEST(sys_copy_file_range(fd, 0, fd_test, 0, CONTSIZE, 0));
74 
75 	SAFE_CLOSE(fd_test);
76 	remove(FILE_MNTED_PATH);
77 	SAFE_CLOSE(fd);
78 
79 	return TST_ERR == EXDEV ? 0 : 1;
80 }
81 
82 #endif /* __COPY_FILE_RANGE_H__ */
83