Whamcloud - gitweb
LU-8347 ldlm: granting conflicting locks
[fs/lustre-release.git] / lustre / tests / ll_sparseness_verify.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  * Lustre is a trademark of Sun Microsystems, Inc.
29  *
30  * lustre/tests/ll_sparseness_verify.c
31  *
32  * The companion to ll_sparseness_write; walk all the bytes in the file.
33  * the bytes at the offsets specified on the command line must be '+', as
34  * previously written by ll_sparseness_write.  All other bytes must be 0.
35  */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <sys/types.h>
43 #include <sys/wait.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <stdarg.h>
47
48 #define BUFSIZE (1024*1024)    
49
50 void error(char *fmt, ...)
51 {
52         va_list ap;
53         va_start(ap, fmt);
54         vfprintf(stderr, fmt, ap);
55         va_end(ap);
56         exit(1);
57 }
58
59 int compare_offsets(const void *a, const void *b)
60 {
61         off_t *A = (off_t *)a;
62         off_t *B = (off_t *)b;
63         return *A - *B;
64 }
65
66 int main(int argc, char **argv)
67 {
68         unsigned int num_offsets, cur_off = 0, i;
69         off_t *offsets, pos = 0, end_of_buf = 0;
70         char *end, *buf;
71         struct stat st;
72         ssize_t ret;
73         int fd;
74
75         if (argc < 3)
76                 error("Usage: %s <filename> <offset> [ offset ... ]\n", 
77                        argv[0]);
78
79         fd = open(argv[1], O_RDONLY);
80         if (fd < 0)
81                 error("couldn't open %s: %s\n", argv[1], strerror(errno));
82
83         buf = malloc(BUFSIZE);
84         if (buf == NULL)
85                 error("can't allocate buffer\n");
86
87         num_offsets = argc - 2;
88         offsets = calloc(sizeof(offsets[0]), num_offsets);
89         for (i = 0; i < num_offsets; i++) {
90                 offsets[i] = strtoul(argv[i + 2], &end, 10);
91                 if (*end) 
92                         error("couldn't parse offset '%s'\n", argv[i + 2]);
93         }
94         qsort(offsets, num_offsets, sizeof(offsets[0]), compare_offsets);
95
96         if (fstat(fd, &st) < 0)
97                 error("stat: %s\n", strerror(errno));
98
99         for (i = 0; pos < st.st_size; i++, pos++) {
100                 if (pos == end_of_buf) {
101                         ret = read(fd, buf, BUFSIZE);
102                         if (ret < 0)
103                                 error("read(): %s\n", strerror(errno));
104                         end_of_buf = pos + ret;
105                         if (end_of_buf > st.st_size)
106                                 error("read %d bytes past file size?\n",
107                                       end_of_buf - st.st_size);
108                         i = 0;
109                 }
110
111                 /* check for 0 when we aren't at a given offset */
112                 if (cur_off >= num_offsets || pos != offsets[cur_off]) {
113                         if (buf[i] != 0) 
114                                 error("found char 0x%x at pos %lu instead of "
115                                        "0x0\n", buf[i], (long)pos);
116                         continue;
117                 }
118
119                 /* the command line asks us to check for + at this offset */
120                 if (buf[i] != '+') 
121                         error("found char 0x%x at pos %lu instead of "
122                                "'.'\n", buf[i], (long)pos);
123
124                 /* skip over duplicate offset arguments */
125                 while (cur_off < num_offsets && offsets[cur_off] == pos)
126                         cur_off++;
127         }
128         /* don't bother freeing or closing.. */
129         return 0;
130 }