Whamcloud - gitweb
branch: HEAD
[fs/lustre-release.git] / lustre / tests / directio.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #ifndef _GNU_SOURCE
5 #define  _GNU_SOURCE
6 #endif
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <sys/mman.h>
16
17 int main(int argc, char **argv)
18 {
19 #ifdef O_DIRECT
20         int fd;
21         char *wbuf, *fname;
22         int blocks, seek_blocks;
23         long len;
24         off64_t seek;
25         struct stat64 st;
26         char pad = 0xba;
27         int action;
28         int rc;
29
30         if (argc < 5 || argc > 6) {
31                 printf("Usage: %s <read/write/rdwr/readhole> file seek nr_blocks [blocksize]\n", argv[0]);
32                 return 1;
33         }
34
35         if (!strcmp(argv[1], "read"))
36                 action = O_RDONLY;
37         else if (!strcmp(argv[1], "write"))
38                 action = O_WRONLY;
39         else if (!strcmp(argv[1], "rdwr"))
40                 action = O_RDWR;
41         else if (!strcmp(argv[1], "readhole")) {
42                 action = O_RDONLY;
43                 pad = 0;
44         } else {
45                 printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]);
46                 return 1;
47         }
48
49         fname = argv[2];
50         seek_blocks = strtoul(argv[3], 0, 0);
51         blocks = strtoul(argv[4], 0, 0);
52         if (!blocks) {
53                 printf("Usage: %s <read/write/rdwr> file seek nr_blocks [blocksize]\n", argv[0]);
54                 return 1;
55         }
56
57         fd = open(fname, O_LARGEFILE | O_DIRECT | O_RDWR | O_CREAT, 0644);
58         if (fd == -1) {
59                 printf("Cannot open %s:  %s\n", fname, strerror(errno));
60                 return 1;
61         }
62
63         if (argc >= 6)
64                 st.st_blksize = strtoul(argv[5], 0, 0);
65         else if (fstat64(fd, &st) < 0) {
66                 printf("Cannot stat %s:  %s\n", fname, strerror(errno));
67                 return 1;
68         }
69
70         printf("directio on %s for %dx%lu bytes \n", fname, blocks,
71                st.st_blksize);
72
73         seek = (off64_t)seek_blocks * (off64_t)st.st_blksize;
74         len = blocks * st.st_blksize;
75
76         wbuf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
77         if (wbuf == MAP_FAILED) {
78                 printf("No memory %s\n", strerror(errno));
79                 return 1;
80         }
81         memset(wbuf, pad, len);
82
83         if (action == O_WRONLY || action == O_RDWR) {
84                 if (lseek64(fd, seek, SEEK_SET) < 0) {
85                         printf("lseek64 failed: %s\n", strerror(errno));
86                         return 1;
87                 }
88
89                 rc = write(fd, wbuf, len);
90                 if (rc != len) {
91                         printf("Write error %s (rc = %d, len = %ld)\n",
92                                strerror(errno), rc, len);
93                         return 1;
94                 }
95         }
96
97         if (action == O_RDONLY || action == O_RDWR) {
98                 char *rbuf;
99
100                 if (lseek64(fd, seek, SEEK_SET) < 0) {
101                         printf("Cannot seek %s\n", strerror(errno));
102                         return 1;
103                 }
104
105                 rbuf =mmap(0,len,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,0,0);
106                 if (rbuf == MAP_FAILED) {
107                         printf("No memory %s\n", strerror(errno));
108                         return 1;
109                 }
110
111                 rc = read(fd, rbuf, len);
112                 if (rc != len) {
113                         printf("Read error: %s rc = %d\n",strerror(errno),rc);
114                         return 1;
115                 }
116
117                 if (memcmp(wbuf, rbuf, len)) {
118                         printf("Data mismatch\n");
119                         return 1;
120                 }
121         }
122
123         printf("PASS\n");
124         return 0;
125 #else /* !O_DIRECT */
126 #warning O_DIRECT not defined, directio test will fail
127         printf("O_DIRECT not defined\n");
128         return 1;
129 #endif /* !O_DIRECT */
130 }