blob: 63ae3ab80b5d0d5a420e54f0b3f48423ef25e161 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
Zeng Linggang67912282014-05-06 15:51:01 +08002 * Copyright (c) International Business Machines Corp., 2001
plars865695b2001-08-27 22:15:12 +00003 * 07/2001 Ported by Wayne Boyer
4 *
Zeng Linggang67912282014-05-06 15:51:01 +08005 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
Zeng Linggang67912282014-05-06 15:51:01 +080019/*
20 * DESCRIPTION
21 * test 1:
22 * Read with an invalid file descriptor, and expect an EBADF.
23 *
24 * test 2:
25 * The parameter passed to read is a directory, check if the errno is
26 * set to EISDIR.
27 *
28 * test 3:
29 * Buf is outside the accessible address space, expect an EFAULT.
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080030 *
31 * test 4:
32 * The file was opened with the O_DIRECT flag, and transfer sizes was not
33 * multiples of the logical block size of the file system, expect an
34 * EINVAL.
35 *
36 * test 5:
37 * The file was opened with the O_DIRECT flag, and the alignment of the
38 * user buffer was not multiples of the logical block size of the file
39 * system, expect an EINVAL.
Zeng Linggang67912282014-05-06 15:51:01 +080040 */
41
42#define _GNU_SOURCE
43
plars865695b2001-08-27 22:15:12 +000044#include <stdio.h>
45#include <errno.h>
46#include <unistd.h>
47#include <fcntl.h>
plars1ad84512002-07-23 13:11:18 +000048#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000049#include "test.h"
Zeng Linggang67912282014-05-06 15:51:01 +080050#include "safe_macros.h"
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080051#include "tst_fs_type.h"
plars865695b2001-08-27 22:15:12 +000052
53char *TCID = "read02";
plars865695b2001-08-27 22:15:12 +000054
Zeng Linggang67912282014-05-06 15:51:01 +080055static int badfd = -1;
Zeng Linggang9018b0a2014-05-27 14:26:23 +080056static int fd2, fd3, fd4 = -1;
Zeng Linggang67912282014-05-06 15:51:01 +080057static char buf[BUFSIZ];
58static void *outside_buf = (void *)-1;
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080059static void *addr4;
60static void *addr5;
plars865695b2001-08-27 22:15:12 +000061
Zeng Linggang9018b0a2014-05-27 14:26:23 +080062static long fs_type;
63
Zeng Linggang67912282014-05-06 15:51:01 +080064static struct test_case_t {
plars865695b2001-08-27 22:15:12 +000065 int *fd;
Zeng Linggang67912282014-05-06 15:51:01 +080066 void **buf;
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080067 size_t count;
Zeng Linggang67912282014-05-06 15:51:01 +080068 int exp_error;
plars865695b2001-08-27 22:15:12 +000069} TC[] = {
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080070 {&badfd, (void **)&buf, 1, EBADF},
71 {&fd2, (void **)&buf, 1, EISDIR},
vapier7ec19d92006-02-27 04:38:56 +000072#ifndef UCLINUX
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080073 {&fd3, &outside_buf, 1, EFAULT},
vapier7ec19d92006-02-27 04:38:56 +000074#endif
Zeng Linggangdbf7cd52014-05-06 15:52:01 +080075 {&fd4, &addr4, 1, EINVAL},
76 {&fd4, &addr5, 4096, EINVAL},
plars865695b2001-08-27 22:15:12 +000077};
78
Zeng Linggang67912282014-05-06 15:51:01 +080079int TST_TOTAL = ARRAY_SIZE(TC);
80static void setup(void);
81static void cleanup(void);
82static void read_verify(const struct test_case_t *);
plars1ad84512002-07-23 13:11:18 +000083
plars74948ad2002-11-14 16:16:14 +000084int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000085{
86 int i;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020087 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020088 const char *msg;
plars865695b2001-08-27 22:15:12 +000089
Zeng Linggang67912282014-05-06 15:51:01 +080090 msg = parse_opts(ac, av, NULL, NULL);
91 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080092 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +000093
94 setup();
95
plars865695b2001-08-27 22:15:12 +000096 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080097 tst_count = 0;
Zeng Linggang67912282014-05-06 15:51:01 +080098 for (i = 0; i < TST_TOTAL; i++)
99 read_verify(&TC[i]);
plars865695b2001-08-27 22:15:12 +0000100 }
101 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800102 tst_exit();
plars865695b2001-08-27 22:15:12 +0000103}
104
Zeng Linggang67912282014-05-06 15:51:01 +0800105static void setup(void)
plars865695b2001-08-27 22:15:12 +0000106{
plars865695b2001-08-27 22:15:12 +0000107 tst_sig(NOFORK, DEF_HANDLER, cleanup);
108
plars865695b2001-08-27 22:15:12 +0000109 TEST_PAUSE;
110
Zeng Linggang67912282014-05-06 15:51:01 +0800111 tst_tmpdir();
plars865695b2001-08-27 22:15:12 +0000112
Zeng Linggangdbf7cd52014-05-06 15:52:01 +0800113 fd2 = SAFE_OPEN(cleanup, ".", O_DIRECTORY);
plars1ad84512002-07-23 13:11:18 +0000114
Zeng Linggang67912282014-05-06 15:51:01 +0800115 SAFE_FILE_PRINTF(cleanup, "test_file", "A");
116
117 fd3 = SAFE_OPEN(cleanup, "test_file", O_RDWR);
118
vapier62b16cf2007-02-09 20:48:23 +0000119#if !defined(UCLINUX)
Zeng Linggang67912282014-05-06 15:51:01 +0800120 outside_buf = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
121 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
vapier62b16cf2007-02-09 20:48:23 +0000122#endif
Zeng Linggangdbf7cd52014-05-06 15:52:01 +0800123
124 addr4 = SAFE_MEMALIGN(cleanup, getpagesize(), (4096 * 10));
125 addr5 = addr4 + 1;
126
Zeng Linggang9018b0a2014-05-27 14:26:23 +0800127 fs_type = tst_fs_type(cleanup, ".");
128 if (fs_type != TST_TMPFS_MAGIC)
129 fd4 = SAFE_OPEN(cleanup, "test_file", O_RDWR | O_DIRECT);
plars865695b2001-08-27 22:15:12 +0000130}
131
Zeng Linggang67912282014-05-06 15:51:01 +0800132static void read_verify(const struct test_case_t *test)
plars865695b2001-08-27 22:15:12 +0000133{
Zeng Linggang9018b0a2014-05-27 14:26:23 +0800134 if (test->fd == &fd4 && *test->fd == -1) {
135 tst_resm(TCONF, "O_DIRECT not supported on %s filesystem",
136 tst_fs_type_name(fs_type));
137 return;
138 }
139
Zeng Linggangdbf7cd52014-05-06 15:52:01 +0800140 TEST(read(*test->fd, *test->buf, test->count));
Garrett Cooper2c282152010-12-16 00:55:50 -0800141
Cyril Hrubis82cfa332014-08-28 10:41:57 +0200142 if (*test->fd == fd4 && TEST_RETURN >= 0) {
143 tst_resm(TPASS,
144 "O_DIRECT unaligned reads fallbacks to buffered I/O");
145 return;
146 }
147
Zeng Linggang67912282014-05-06 15:51:01 +0800148 if (TEST_RETURN != -1) {
149 tst_resm(TFAIL, "call succeeded unexpectedly");
150 return;
151 }
152
Zeng Linggang67912282014-05-06 15:51:01 +0800153 if (TEST_ERRNO == test->exp_error) {
154 tst_resm(TPASS | TTERRNO, "expected failure");
155 } else {
156 tst_resm(TFAIL | TTERRNO, "unexpected error expected %d",
157 test->exp_error);
158 }
159}
160
161static void cleanup(void)
162{
Zeng Linggangdbf7cd52014-05-06 15:52:01 +0800163 free(addr4);
164
165 if (fd4 > 0)
166 close(fd4);
167
Zeng Linggang67912282014-05-06 15:51:01 +0800168 if (fd3 > 0)
169 close(fd3);
170
171 if (fd2 > 0)
172 close(fd2);
173
174 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700175}