Whamcloud - gitweb
Test program to generate the "test_brw" pattern from user-space for a file.
[fs/lustre-release.git] / lustre / tests / test_brw.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <sys/mman.h>
8
9 // not correctly in the headers yet!!
10 //#define O_DIRECT 0
11 #ifndef O_DIRECT
12 #define O_DIRECT         040000 /* direct disk access hint */
13 #endif
14
15 #define BLOCKSIZE 4096
16 #define CERROR(fmt, arg...) fprintf(stderr, fmt, ## arg)
17 #define __u64 long long
18 #define LASSERT(v) do {} while(0)
19 #define HTON__u64(v) (v)
20 #define LPU64 "%Ld"
21 #define LPX64 "%Lx"
22
23 #define LPDS sizeof(__u64)
24 int page_debug_setup(void *addr, int len, __u64 off, __u64 id)
25 {
26         LASSERT(addr);
27
28         off = HTON__u64(off);
29         id = HTON__u64(id);
30         memcpy(addr, (char *)&off, LPDS);
31         memcpy(addr + LPDS, (char *)&id, LPDS);
32
33         addr += len - LPDS - LPDS;
34         memcpy(addr, (char *)&off, LPDS);
35         memcpy(addr + LPDS, (char *)&id, LPDS);
36
37         return 0;
38 }
39
40 int page_debug_check(char *who, void *addr, int end, __u64 off, __u64 id)
41 {
42         __u64 ne_off;
43         int err = 0;
44
45         LASSERT(addr);
46
47         ne_off = HTON__u64(off);
48         id = HTON__u64(id);
49         if (memcmp(addr, (char *)&ne_off, LPDS)) {
50                 CERROR("%s: for offset "LPU64" off: "LPX64" != "LPX64"\n",
51                        who, off, *(__u64 *)addr, ne_off);
52                 err = -EINVAL;
53         }
54         if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
55                 CERROR("%s: for offset "LPU64" id: "LPX64" != "LPX64"\n",
56                        who, off, *(__u64 *)(addr + LPDS), id);
57                 err = -EINVAL;
58         }
59
60         addr += end - LPDS - LPDS;
61         if (memcmp(addr, (char *)&ne_off, LPDS)) {
62                 CERROR("%s: for offset "LPU64" end off: "LPX64" != "LPX64"\n",
63                        who, off, *(__u64 *)addr, ne_off);
64                 err = -EINVAL;
65         }
66         if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
67                 CERROR("%s: for offset "LPU64" end id: "LPX64" != "LPX64"\n",
68                        who, off, *(__u64 *)(addr + LPDS), id);
69                 err = -EINVAL;
70         }
71
72         return err;
73 }
74 #undef LPDS
75
76 int main(int argc, char **argv)
77 {
78         int fd;
79         char *buf;
80         long pg_vec, count;
81         long len;
82         long long end, offset;
83         long objid = 3;
84         int rc;
85
86         if (argc < 4 || argc > 5) {
87                 fprintf(stderr,
88                         "usage: %s file pages_per_vec count [objid]\n",
89                         argv[0]);
90                 return 1;
91         }
92
93         pg_vec = strtoul(argv[2], 0, 0);
94         count = strtoul(argv[3], 0, 0);
95         len = pg_vec * BLOCKSIZE;
96         end = (long long)count * len;
97         printf("directio on %s for %ldx%ld pages \n", argv[1], count, pg_vec);
98
99         buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
100         if (!buf) {
101                 fprintf(stderr, "No memory %s\n", strerror(errno));
102                 return 2;
103         }
104
105         fd = open(argv[1], O_DIRECT | O_RDWR | O_CREAT);
106         if (fd == -1) {
107                 fprintf(stderr, "Cannot open %s:  %s\n", argv[1],
108                         strerror(errno));
109                 return 3;
110         }
111
112         for (offset = 0; offset < end; offset += len) {
113                 int i;
114
115                 for (i = 0; i < len; i += BLOCKSIZE)
116                         page_debug_setup(buf + i, BLOCKSIZE, offset + i, objid);
117
118                 rc = write(fd, buf, len);
119
120                 for (i = 0; i < len; i += BLOCKSIZE) {
121                         if (page_debug_check("write", buf + i, BLOCKSIZE,
122                                              offset + i, objid))
123                                 return 10;
124                 }
125
126                 if (rc != len) {
127                         fprintf(stderr, "Write error: %s, rc %d\n",
128                                 strerror(errno), rc);
129                         return 4;
130                 }
131         }
132
133         if ( lseek(fd, 0, SEEK_SET) != 0 ) {
134                 fprintf(stderr, "Cannot seek %s\n", strerror(errno));
135                 return 5;
136         }
137
138         for (offset = 0; offset < end; offset += len) {
139                 int i;
140
141                 rc = read(fd, buf, len);
142                 if (rc != len) {
143                         fprintf(stderr, "Read error: %s, rc %d\n",
144                                 strerror(errno), rc);
145                         return 6;
146                 }
147
148                 for (i = 0; i < len; i += BLOCKSIZE) {
149                         if (page_debug_check("read", buf + i, BLOCKSIZE,
150                                              offset + i, objid))
151                                 return 11;
152                 }
153         }
154
155         return 0;
156 }