1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) International Business Machines Corp., 2001
4*49cdfc7eSAndroid Build Coastguard Worker * Ported to LTP: Wayne Boyer
5*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2017 Fujitsu Ltd.
6*49cdfc7eSAndroid Build Coastguard Worker * 04/2017 Modified by Jinhui Huang
7*49cdfc7eSAndroid Build Coastguard Worker */
8*49cdfc7eSAndroid Build Coastguard Worker /*
9*49cdfc7eSAndroid Build Coastguard Worker * DESCRIPTION
10*49cdfc7eSAndroid Build Coastguard Worker * test 1:
11*49cdfc7eSAndroid Build Coastguard Worker * Read with an invalid file descriptor, and expect an EBADF.
12*49cdfc7eSAndroid Build Coastguard Worker *
13*49cdfc7eSAndroid Build Coastguard Worker * test 2:
14*49cdfc7eSAndroid Build Coastguard Worker * The parameter passed to read is a directory, check if the errno is
15*49cdfc7eSAndroid Build Coastguard Worker * set to EISDIR.
16*49cdfc7eSAndroid Build Coastguard Worker *
17*49cdfc7eSAndroid Build Coastguard Worker * test 3:
18*49cdfc7eSAndroid Build Coastguard Worker * Buf is outside the accessible address space, expect an EFAULT.
19*49cdfc7eSAndroid Build Coastguard Worker *
20*49cdfc7eSAndroid Build Coastguard Worker * test 4:
21*49cdfc7eSAndroid Build Coastguard Worker * The file was opened with the O_DIRECT flag, and transfer sizes was not
22*49cdfc7eSAndroid Build Coastguard Worker * multiples of the logical block size of the file system, expect an
23*49cdfc7eSAndroid Build Coastguard Worker * EINVAL.
24*49cdfc7eSAndroid Build Coastguard Worker *
25*49cdfc7eSAndroid Build Coastguard Worker * test 5:
26*49cdfc7eSAndroid Build Coastguard Worker * The file was opened with the O_DIRECT flag, and the alignment of the
27*49cdfc7eSAndroid Build Coastguard Worker * user buffer was not multiples of the logical block size of the file
28*49cdfc7eSAndroid Build Coastguard Worker * system, expect an EINVAL.
29*49cdfc7eSAndroid Build Coastguard Worker */
30*49cdfc7eSAndroid Build Coastguard Worker
31*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
34*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
35*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
36*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
37*49cdfc7eSAndroid Build Coastguard Worker
38*49cdfc7eSAndroid Build Coastguard Worker static int badfd = -1;
39*49cdfc7eSAndroid Build Coastguard Worker static int fd2, fd3, fd4 = -1;
40*49cdfc7eSAndroid Build Coastguard Worker static char buf[BUFSIZ];
41*49cdfc7eSAndroid Build Coastguard Worker static void *bufaddr = buf;
42*49cdfc7eSAndroid Build Coastguard Worker static void *outside_buf = (void *)-1;
43*49cdfc7eSAndroid Build Coastguard Worker static void *addr4;
44*49cdfc7eSAndroid Build Coastguard Worker static void *addr5;
45*49cdfc7eSAndroid Build Coastguard Worker static long fs_type;
46*49cdfc7eSAndroid Build Coastguard Worker
47*49cdfc7eSAndroid Build Coastguard Worker static struct tcase {
48*49cdfc7eSAndroid Build Coastguard Worker int *fd;
49*49cdfc7eSAndroid Build Coastguard Worker void **buf;
50*49cdfc7eSAndroid Build Coastguard Worker size_t count;
51*49cdfc7eSAndroid Build Coastguard Worker int exp_error;
52*49cdfc7eSAndroid Build Coastguard Worker } tcases[] = {
53*49cdfc7eSAndroid Build Coastguard Worker {&badfd, &bufaddr, 1, EBADF},
54*49cdfc7eSAndroid Build Coastguard Worker {&fd2, &bufaddr, 1, EISDIR},
55*49cdfc7eSAndroid Build Coastguard Worker {&fd3, &outside_buf, 1, EFAULT},
56*49cdfc7eSAndroid Build Coastguard Worker {&fd4, &addr4, 1, EINVAL},
57*49cdfc7eSAndroid Build Coastguard Worker {&fd4, &addr5, 4096, EINVAL},
58*49cdfc7eSAndroid Build Coastguard Worker };
59*49cdfc7eSAndroid Build Coastguard Worker
verify_read(unsigned int n)60*49cdfc7eSAndroid Build Coastguard Worker static void verify_read(unsigned int n)
61*49cdfc7eSAndroid Build Coastguard Worker {
62*49cdfc7eSAndroid Build Coastguard Worker struct tcase *tc = &tcases[n];
63*49cdfc7eSAndroid Build Coastguard Worker
64*49cdfc7eSAndroid Build Coastguard Worker if (tc->fd == &fd4 && *tc->fd == -1) {
65*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "O_DIRECT not supported on %s filesystem",
66*49cdfc7eSAndroid Build Coastguard Worker tst_fs_type_name(fs_type));
67*49cdfc7eSAndroid Build Coastguard Worker return;
68*49cdfc7eSAndroid Build Coastguard Worker }
69*49cdfc7eSAndroid Build Coastguard Worker
70*49cdfc7eSAndroid Build Coastguard Worker TEST(read(*tc->fd, *tc->buf, tc->count));
71*49cdfc7eSAndroid Build Coastguard Worker
72*49cdfc7eSAndroid Build Coastguard Worker if (*tc->fd == fd4 && TST_RET >= 0) {
73*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS,
74*49cdfc7eSAndroid Build Coastguard Worker "O_DIRECT unaligned reads fallbacks to buffered I/O");
75*49cdfc7eSAndroid Build Coastguard Worker return;
76*49cdfc7eSAndroid Build Coastguard Worker }
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET != -1) {
79*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "read() succeeded unexpectedly");
80*49cdfc7eSAndroid Build Coastguard Worker return;
81*49cdfc7eSAndroid Build Coastguard Worker }
82*49cdfc7eSAndroid Build Coastguard Worker
83*49cdfc7eSAndroid Build Coastguard Worker if (TST_ERR == tc->exp_error) {
84*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS | TTERRNO, "read() failed as expected");
85*49cdfc7eSAndroid Build Coastguard Worker } else {
86*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "read() failed unexpectedly, "
87*49cdfc7eSAndroid Build Coastguard Worker "expected %s", tst_strerrno(tc->exp_error));
88*49cdfc7eSAndroid Build Coastguard Worker }
89*49cdfc7eSAndroid Build Coastguard Worker }
90*49cdfc7eSAndroid Build Coastguard Worker
setup(void)91*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
92*49cdfc7eSAndroid Build Coastguard Worker {
93*49cdfc7eSAndroid Build Coastguard Worker fd2 = SAFE_OPEN(".", O_DIRECTORY);
94*49cdfc7eSAndroid Build Coastguard Worker
95*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF("test_file", "A");
96*49cdfc7eSAndroid Build Coastguard Worker
97*49cdfc7eSAndroid Build Coastguard Worker fd3 = SAFE_OPEN("test_file", O_RDWR);
98*49cdfc7eSAndroid Build Coastguard Worker
99*49cdfc7eSAndroid Build Coastguard Worker outside_buf = SAFE_MMAP(0, 1, PROT_NONE,
100*49cdfc7eSAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
101*49cdfc7eSAndroid Build Coastguard Worker
102*49cdfc7eSAndroid Build Coastguard Worker addr4 = SAFE_MEMALIGN(getpagesize(), (4096 * 10));
103*49cdfc7eSAndroid Build Coastguard Worker addr5 = addr4 + 1;
104*49cdfc7eSAndroid Build Coastguard Worker
105*49cdfc7eSAndroid Build Coastguard Worker fs_type = tst_fs_type(".");
106*49cdfc7eSAndroid Build Coastguard Worker if (fs_type != TST_TMPFS_MAGIC)
107*49cdfc7eSAndroid Build Coastguard Worker fd4 = SAFE_OPEN("test_file", O_RDWR | O_DIRECT);
108*49cdfc7eSAndroid Build Coastguard Worker }
109*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)110*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
111*49cdfc7eSAndroid Build Coastguard Worker {
112*49cdfc7eSAndroid Build Coastguard Worker free(addr4);
113*49cdfc7eSAndroid Build Coastguard Worker
114*49cdfc7eSAndroid Build Coastguard Worker if (fd4 > 0)
115*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd4);
116*49cdfc7eSAndroid Build Coastguard Worker
117*49cdfc7eSAndroid Build Coastguard Worker if (fd3 > 0)
118*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd3);
119*49cdfc7eSAndroid Build Coastguard Worker
120*49cdfc7eSAndroid Build Coastguard Worker if (fd2 > 0)
121*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd2);
122*49cdfc7eSAndroid Build Coastguard Worker }
123*49cdfc7eSAndroid Build Coastguard Worker
124*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
125*49cdfc7eSAndroid Build Coastguard Worker .tcnt = ARRAY_SIZE(tcases),
126*49cdfc7eSAndroid Build Coastguard Worker .test = verify_read,
127*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
128*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup,
129*49cdfc7eSAndroid Build Coastguard Worker .needs_tmpdir = 1,
130*49cdfc7eSAndroid Build Coastguard Worker };
131