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