1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2019 SUSE LLC
4f08c3bdfSopenharmony_ci * Author: Jorik Cronenberg <jcronenberg@suse.de>
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Test vmsplice() from a pipe into user memory
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci#define _GNU_SOURCE
10f08c3bdfSopenharmony_ci
11f08c3bdfSopenharmony_ci#include "tst_test.h"
12f08c3bdfSopenharmony_ci#include "lapi/fcntl.h"
13f08c3bdfSopenharmony_ci#include "lapi/vmsplice.h"
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#define TEST_BLOCK_SIZE (64*1024)	/* 64K */
17f08c3bdfSopenharmony_ci
18f08c3bdfSopenharmony_cistatic char buffer[TEST_BLOCK_SIZE];
19f08c3bdfSopenharmony_cistatic struct iovec *iov;
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_cistatic void vmsplice_test(void)
22f08c3bdfSopenharmony_ci{
23f08c3bdfSopenharmony_ci	int written, i;
24f08c3bdfSopenharmony_ci	int pipes[2];
25f08c3bdfSopenharmony_ci	char *arr_write = iov->iov_base;
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci	memset(iov->iov_base, 0, iov->iov_len);
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_ci	SAFE_PIPE(pipes);
30f08c3bdfSopenharmony_ci	SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buffer, TEST_BLOCK_SIZE);
31f08c3bdfSopenharmony_ci	written = vmsplice(pipes[0], iov, 1, 0);
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci	if (written < 0)
34f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "vmsplice() failed");
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci	if (written == 0) {
37f08c3bdfSopenharmony_ci		tst_res(TFAIL, "vmsplice() didn't write anything");
38f08c3bdfSopenharmony_ci	} else {
39f08c3bdfSopenharmony_ci		for (i = 0; i < TEST_BLOCK_SIZE; i++) {
40f08c3bdfSopenharmony_ci			if (arr_write[i] != buffer[i]) {
41f08c3bdfSopenharmony_ci				tst_res(TFAIL,
42f08c3bdfSopenharmony_ci					"Wrong data in user memory at %i", i);
43f08c3bdfSopenharmony_ci				break;
44f08c3bdfSopenharmony_ci			}
45f08c3bdfSopenharmony_ci		}
46f08c3bdfSopenharmony_ci		if (i == written)
47f08c3bdfSopenharmony_ci			tst_res(TPASS, "Spliced correctly into user memory");
48f08c3bdfSopenharmony_ci	}
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	SAFE_CLOSE(pipes[1]);
51f08c3bdfSopenharmony_ci	SAFE_CLOSE(pipes[0]);
52f08c3bdfSopenharmony_ci}
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_cistatic void setup(void)
55f08c3bdfSopenharmony_ci{
56f08c3bdfSopenharmony_ci	int i;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	for (i = 0; i < TEST_BLOCK_SIZE; i++)
59f08c3bdfSopenharmony_ci		buffer[i] = i & 0xff;
60f08c3bdfSopenharmony_ci}
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_cistatic struct tst_test test = {
63f08c3bdfSopenharmony_ci	.setup = setup,
64f08c3bdfSopenharmony_ci	.test_all = vmsplice_test,
65f08c3bdfSopenharmony_ci	.bufs = (struct tst_buffers []) {
66f08c3bdfSopenharmony_ci		{&iov, .iov_sizes = (int[]){TEST_BLOCK_SIZE, -1}},
67f08c3bdfSopenharmony_ci		{}
68f08c3bdfSopenharmony_ci	}
69f08c3bdfSopenharmony_ci};
70