Whamcloud - gitweb
LU-82 Remove useless clio locks
[fs/lustre-release.git] / lustre / utils / obdio.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/utils/obdio.c
37  *
38  * Author: Eric Barton <eeb@clusterfs.com>
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <errno.h>
44 #include <string.h>
45
46 #include <liblustre.h>
47 #include "obdiolib.h"
48
49 int
50 obdio_test_fixed_extent (struct obdio_conn *conn,
51                          __u32 myhid, __u32 mypid,
52                          int reps, int locked, __u64 oid,
53                          __u64 offset, __u32 size)
54 {
55         struct lustre_handle lh;
56         void                *space;
57         void                *buffer;
58         __u32               *ibuf;
59         int                  i;
60         int                  j;
61         int                  rc = 0;
62
63         space = obdio_alloc_aligned_buffer (&buffer, size);
64         if (space == NULL) {
65                 fprintf (stderr, "Can't allocate buffer size %d\n", size);
66                 return (-1);
67         }
68
69         for (i = 0; i < reps; i++) {
70                 ibuf = (__u32 *) buffer;
71                 for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
72                         ibuf[0] = myhid;
73                         ibuf[1] = mypid;
74                         ibuf[2] = i;
75                         ibuf[3] = j;
76                         ibuf += 4;
77                 }
78
79                 if (locked) {
80                         rc = obdio_enqueue(conn, oid, LCK_PW, offset, size,&lh);
81                         if (rc != 0) {
82                                 fprintf(stderr, "Error on enqueue "LPX64" @ "
83                                         LPU64" for %u: %s\n",
84                                         oid, offset, size, strerror (errno));
85                                 goto out;
86                         }
87                 }
88
89                 rc = obdio_pwrite (conn, oid, buffer, size, offset);
90                 if (rc != 0) {
91                         fprintf(stderr, "Error writing "LPX64" @ "LPU64
92                                 " for %u: %s\n",
93                                 oid, offset, size, strerror (errno));
94                         if (locked)
95                                 obdio_cancel (conn, &lh);
96                         rc = -1;
97                         goto out;
98                 }
99
100                 memset (buffer, 0xbb, size);
101
102                 rc = obdio_pread (conn, oid, buffer, size, offset);
103                 if (rc != 0) {
104                         fprintf(stderr, "Error reading "LPX64" @ "LPU64
105                                 " for %u: %s\n",
106                                 oid, offset, size, strerror (errno));
107                         if (locked)
108                                 obdio_cancel (conn, &lh);
109                         rc = -1;
110                         goto out;
111                 }
112
113                 if (locked) {
114                         rc = obdio_cancel (conn, &lh);
115                         if (rc != 0) {
116                                 fprintf(stderr, "Error on cancel "LPX64" @ "
117                                         LPU64" for %u: %s\n",
118                                         oid, offset, size, strerror (errno));
119                                 rc = -1;
120                                 goto out;
121                         }
122                 }
123
124                 ibuf = (__u32 *) buffer;
125                 for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
126                         if (ibuf[0] != myhid ||
127                             ibuf[1] != mypid ||
128                             ibuf[2] != i ||
129                             ibuf[3] != j) {
130                                 fprintf(stderr, "Error checking "LPX64" @ "
131                                         LPU64" for %u, chunk %d\n",
132                                         oid, offset, size, j);
133                                 fprintf(stderr, "Expected [%x,%x,%x,%x], "
134                                         "got [%x,%x,%x,%x]\n",
135                                         myhid, mypid, i, j,
136                                         ibuf[0], ibuf[1], ibuf[2], ibuf[3]);
137                                 rc = -1;
138                                 goto out;
139                         }
140                         ibuf += 4;
141                 }
142         }
143  out:
144         free (space);
145         return (rc);
146 }
147
148 int
149 parse_kmg (__u64 *valp, char *str)
150 {
151         __u64           val;
152         char            mod[32];
153
154         switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod))
155         {
156         default:
157                 return (-1);
158
159         case 1:
160                 *valp = val;
161                 return (0);
162
163         case 2:
164                 switch (*mod)
165                 {
166                 case 'g':
167                 case 'G':
168                         *valp = val << 30;
169                         return (0);
170
171                 case 'm':
172                 case 'M':
173                         *valp = val << 20;
174                         return (0);
175
176                 case 'k':
177                 case 'K':
178                         *valp = val << 10;
179                         return (0);
180
181                 default:
182                         *valp = val;
183                         return (0);
184                 }
185         }
186 }
187
188 void
189 usage (char *cmdname, int help)
190 {
191         char *name = strrchr (cmdname, '/');
192
193         if (name == NULL)
194                 name = cmdname;
195
196         fprintf (help ? stdout : stderr,
197                  "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n",
198                  name);
199 }
200
201 int
202 main (int argc, char **argv)
203 {
204         __u32             mypid = getpid ();
205         __u32             myhid = gethostid ();
206         __u64             oid;
207         __u64             base_offset = 0;
208         __u32             size = 0;
209         int                set_size = 0;
210         int                device = -1;
211         int                reps = 1;
212         int                locked = 0;
213         char              *end;
214         struct obdio_conn *conn;
215         __u64              val;
216         int                v1;
217         int                v2;
218         int                rc;
219         int                c;
220
221         while ((c = getopt (argc, argv, "hi:s:o:d:n:l")) != -1)
222                 switch (c) {
223                 case 'h':
224                         usage (argv[0], 1);
225                         return (0);
226
227                 case 'i':
228                         switch (sscanf (optarg, "%i.%i", &v1, &v2)) {
229                         case 1:
230                                 mypid = v1;
231                                 break;
232                         case 2:
233                                 myhid = v1;
234                                 mypid = v2;
235                                 break;
236                         default:
237                                 fprintf (stderr, "Can't parse id %s\n",
238                                          optarg);
239                                 return (1);
240                         }
241                         break;
242
243                 case 's':
244                         if (parse_kmg (&val, optarg) != 0) {
245                                 fprintf (stderr, "Can't parse size %s\n",
246                                          optarg);
247                                 return (1);
248                         }
249                         size = (__u32)val;
250                         set_size++;
251                         break;
252
253                 case 'o':
254                         if (parse_kmg (&val, optarg) != 0) {
255                                 fprintf (stderr, "Can't parse offset %s\n",
256                                          optarg);
257                                 return (1);
258                         }
259                         base_offset = val;
260                         break;
261
262                 case 'd':
263                         device = strtol (optarg, &end, 0);
264                         if (end == optarg || *end != 0 || device < 0) {
265                                 fprintf (stderr, "Can't parse device %s\n",
266                                          optarg);
267                                 return (1);
268                         }
269                         break;
270                 case 'n':
271                         if (parse_kmg (&val, optarg) != 0) {
272                                 fprintf (stderr, "Can't parse reps %s\n",
273                                          optarg);
274                                 return (1);
275                         }
276                         reps = (int)val;
277                         break;
278                 case 'l':
279                         locked = 1;
280                         break;
281                 default:
282                         usage (argv[0], 0);
283                         return (1);
284         }
285
286         if (!set_size ||
287             device < 0 ||
288             optind == argc) {
289                 fprintf (stderr, "No %s specified\n",
290                          !set_size ? "size" :
291                          device < 0 ? "device" : "object id");
292                 return (1);
293         }
294
295         oid = strtoull (argv[optind], &end, 0);
296         if (end == argv[optind] || *end != 0) {
297                 fprintf (stderr, "Can't parse object id %s\n",
298                          argv[optind]);
299                 return (1);
300         }
301
302         conn = obdio_connect (device);
303         if (conn == NULL)
304                 return (1);
305
306         rc = obdio_test_fixed_extent(conn, myhid, mypid, reps, locked,
307                                      oid, base_offset, size);
308
309         obdio_disconnect(conn, 0);
310
311         return (rc == 0 ? 0 : 1);
312 }