Whamcloud - gitweb
LU-6245 uapi: move libcfs/lnet UAPI header into own uapi directory
[fs/lustre-release.git] / lustre / utils / lustre_lfsck.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,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License version 2 for more details.  A copy is
14  * included in the COPYING file that accompanied this code.
15
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2012, 2016, Intel Corporation.
24  */
25 /*
26  * lustre/utils/lustre_lfsck.c
27  *
28  * Lustre user-space tools for LFSCK.
29  *
30  * Author: Fan Yong <yong.fan@whamcloud.com>
31  */
32
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
38 #include <getopt.h>
39 #include <sys/ioctl.h>
40 #include <time.h>
41
42 #include "obdctl.h"
43 #include "lustreapi_internal.h"
44
45 #include <lustre/lustre_lfsck_user.h>
46 #include <linux/lnet/lnetctl.h>
47 #include <linux/lustre_ioctl.h>
48 /* Needs to be last to avoid clashes */
49 #include <libcfs/util/ioctl.h>
50 #include <libcfs/util/param.h>
51
52 static struct option long_opt_start[] = {
53 { .val = 'A',   .name = "all",                  .has_arg = no_argument },
54 { .val = 'c',   .name = "create_ostobj",        .has_arg = optional_argument },
55 { .val = 'c',   .name = "create-ostobj",        .has_arg = optional_argument },
56 { .val = 'C',   .name = "create_mdtobj",        .has_arg = optional_argument },
57 { .val = 'C',   .name = "create-mdtobj",        .has_arg = optional_argument },
58 { .val = 'd',   .name = "delay_create_ostobj",  .has_arg = optional_argument },
59 { .val = 'd',   .name = "delay-create-ostobj",  .has_arg = optional_argument },
60 { .val = 'e',   .name = "error",                .has_arg = required_argument },
61 { .val = 'h',   .name = "help",                 .has_arg = no_argument },
62 { .val = 'M',   .name = "device",               .has_arg = required_argument },
63 { .val = 'n',   .name = "dryrun",               .has_arg = optional_argument },
64 { .val = 'o',   .name = "orphan",               .has_arg = no_argument },
65 { .val = 'r',   .name = "reset",                .has_arg = no_argument },
66 { .val = 's',   .name = "speed",                .has_arg = required_argument },
67 { .val = 't',   .name = "type",                 .has_arg = required_argument },
68 { .val = 'w',   .name = "window_size",          .has_arg = required_argument },
69 { .val = 'w',   .name = "window-size",          .has_arg = required_argument },
70 { .name = NULL } };
71
72 static struct option long_opt_stop[] = {
73         { .val = 'A',   .name = "all",          .has_arg = no_argument },
74         { .val = 'h',   .name = "help",         .has_arg = no_argument },
75         { .val = 'M',   .name = "device",       .has_arg = required_argument },
76         { .name = NULL } };
77
78 static struct option long_opt_query[] = {
79         { .val = 'h',   .name = "help",         .has_arg = no_argument },
80         { .val = 'M',   .name = "device",       .has_arg = required_argument },
81         { .val = 't',   .name = "type",         .has_arg = required_argument },
82         { .val = 'w',   .name = "wait",         .has_arg = no_argument },
83         { .name = NULL } };
84
85 struct lfsck_type_name {
86         char            *ltn_name;
87         enum lfsck_type  ltn_type;
88 };
89
90 static struct lfsck_type_name lfsck_types_names[] = {
91         { .ltn_name = "all",            .ltn_type = LFSCK_TYPES_SUPPORTED },
92         { .ltn_name = "default",        .ltn_type = LFSCK_TYPES_DEF },
93         { .ltn_name = "layout",         .ltn_type = LFSCK_TYPE_LAYOUT },
94         { .ltn_name = "namespace",      .ltn_type = LFSCK_TYPE_NAMESPACE },
95         { .ltn_name = "scrub",          .ltn_type = LFSCK_TYPE_SCRUB },
96         { .ltn_name = NULL } };
97
98 static enum lfsck_type lfsck_name2type(const char *name)
99 {
100         int i;
101
102         for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) {
103                 if (strcmp(lfsck_types_names[i].ltn_name, name) == 0)
104                         return lfsck_types_names[i].ltn_type;
105         }
106         return -1;
107 }
108
109 static const char *lfsck_type2name(__u16 type)
110 {
111         int i;
112
113         for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) {
114                 if (type == lfsck_types_names[i].ltn_type)
115                         return lfsck_types_names[i].ltn_name;
116         }
117
118         return NULL;
119 }
120
121 static void usage_start(void)
122 {
123         fprintf(stderr, "start LFSCK\n"
124                 "usage:\n"
125                 "lfsck_start [-M | --device {MDT,OST}_device]\n"
126                 "            [-A | --all] [-c | --create_ostobj [on | off]]\n"
127                 "            [-C | --create_mdtobj [on | off]]\n"
128                 "            [-d | --delay_create_ostobj [on | off]]\n"
129                 "            [-e | --error {continue | abort}] [-h | --help]\n"
130                 "            [-n | --dryrun [on | off]] [-o | --orphan]\n"
131                 "            [-r | --reset] [-s | --speed ops_per_sec_limit]\n"
132                 "            [-t | --type check_type[,check_type...]]\n"
133                 "            [-w | --window_size size]\n"
134                 "options:\n"
135                 "-M: device to start LFSCK/scrub on\n"
136                 "-A: start LFSCK on all nodes via the specified MDT device "
137                     "(see \"-M\" option) by single LFSCK command\n"
138                 "-c: create the lost OST-object for dangling LOV EA "
139                     "(default 'off', or 'on')\n"
140                 "-C: create the lost MDT-object for dangling name entry "
141                     "(default 'off', or 'on')\n"
142                 "-d: delay create the lost OST-object for dangling LOV EA "
143                     "until orphan OST-objects handled (default 'off', or 'on')\n"
144                 "-e: error handle mode (default 'continue', or 'abort')\n"
145                 "-h: this help message\n"
146                 "-n: check with no modification (default 'off', or 'on')\n"
147                 "-o: repair orphan OST-objects\n"
148                 "-r: reset scanning to the start of the device\n"
149                 "-s: maximum items to be scanned per second "
150                     "(default '%d' = no limit)\n"
151                 "-t: check type(s) to be performed (default all)\n"
152                 "-w: window size for async requests pipeline\n",
153                 LFSCK_SPEED_NO_LIMIT);
154 }
155
156 static void usage_stop(void)
157 {
158         fprintf(stderr, "stop LFSCK\n"
159                 "usage:\n"
160                 "lfsck_stop [-M | --device {MDT,OST}_device]\n"
161                 "           [-A | --all] [-h | --help]\n"
162                 "options:\n"
163                 "-M: device to stop LFSCK/scrub on\n"
164                 "-A: stop LFSCK on all nodes via the specified MDT device "
165                     "(see \"-M\" option) by single LFSCK command\n"
166                 "-h: this help message\n");
167 }
168
169 static void usage_query(void)
170 {
171         fprintf(stderr, "check the LFSCK global status\n"
172                 "usage:\n"
173                 "lfsck_query [-M | --device MDT_device] [-h | --help]\n"
174                 "            [-t | --type check_type[,check_type...]]\n"
175                 "            [-t | --wait]\n"
176                 "options:\n"
177                 "-M: device to query LFSCK on\n"
178                 "-t: LFSCK type(s) to be queried (default is all)\n"
179                 "-h: this help message\n"
180                 "-w: do not return until LFSCK not running\n");
181 }
182
183 static int lfsck_pack_dev(struct obd_ioctl_data *data, char *device, char *arg)
184 {
185         int len = strlen(arg) + 1;
186
187         if (len > MAX_OBD_NAME) {
188                 fprintf(stderr, "device name is too long. "
189                         "Valid length should be less than %d\n", MAX_OBD_NAME);
190                 return -EINVAL;
191         }
192
193         memcpy(device, arg, len);
194         data->ioc_inlbuf4 = device;
195         data->ioc_inllen4 = len;
196         data->ioc_dev = OBD_DEV_BY_DEVNAME;
197         return 0;
198 }
199
200 static int lfsck_get_dev_name(struct obd_ioctl_data *data, char *device,
201                               int types, bool multipe_devices)
202 {
203         glob_t param = { 0 };
204         char *ptr;
205         int rc;
206         int i;
207
208         rc = cfs_get_param_paths(&param, "mdd/*-MDT*");
209         if (rc) {
210                 if (multipe_devices || errno != ENOENT ||
211                     types & LFSCK_TYPE_NAMESPACE) {
212                         fprintf(stderr, "Fail to get device name: rc = %d\n."
213                                 "You can specify the device explicitly "
214                                 "via '-M' option.\n", rc);
215                         return rc;
216                 }
217
218                 rc = cfs_get_param_paths(&param, "obdfilter/*-OST*");
219                 if (rc) {
220                         fprintf(stderr, "Fail to get device name: rc = %d\n."
221                                 "You can specify the device explicitly "
222                                 "via '-M' option.\n", rc);
223                         return rc;
224                 }
225         }
226
227         if (param.gl_pathc == 1)
228                 goto pack;
229
230         if (!multipe_devices) {
231                 fprintf(stderr,
232                         "Detect multiple devices on current node. "
233                         "Please specify the device explicitly "
234                         "via '-M' option or '-A' option for all.\n");
235                 rc = -EINVAL;
236                 goto out;
237         }
238
239         ptr = strrchr(param.gl_pathv[0], '-');
240         if (ptr == NULL) {
241                 rc = -EINVAL;
242                 goto out;
243         }
244
245         for (i = 1; i < param.gl_pathc; i++) {
246                 char *ptr2 = strrchr(param.gl_pathv[i], '-');
247
248                 if (ptr2 == NULL) {
249                         rc = -EINVAL;
250                         goto out;
251                 }
252
253                 if ((ptr - param.gl_pathv[0]) != (ptr2 - param.gl_pathv[i]) ||
254                     strncmp(param.gl_pathv[0], param.gl_pathv[i],
255                             (ptr - param.gl_pathv[0])) != 0) {
256                         fprintf(stderr,
257                                 "Detect multiple filesystems on current node. "
258                                 "Please specify the device explicitly "
259                                 "via '-M' option.\n");
260                         rc = -EINVAL;
261                         goto out;
262                 }
263         }
264
265 pack:
266         rc = lfsck_pack_dev(data, device, basename(param.gl_pathv[0]));
267
268 out:
269         cfs_free_param_data(&param);
270
271         return rc;
272 }
273
274 int jt_lfsck_start(int argc, char **argv)
275 {
276         struct obd_ioctl_data data;
277         char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
278         char device[MAX_OBD_NAME];
279         struct lfsck_start start;
280         char *short_opts = "Ac::C::d::e:hM:n::ors:t:w:";
281         int opt, index, rc, val, i;
282
283         memset(&data, 0, sizeof(data));
284         memset(&start, 0, sizeof(start));
285         memset(device, 0, MAX_OBD_NAME);
286         start.ls_version = LFSCK_VERSION_V1;
287         start.ls_active = LFSCK_TYPES_ALL;
288
289         /* Reset the 'optind' for the case of getopt_long() called multiple
290          * times under the same lctl. */
291         optind = 0;
292         while ((opt = getopt_long(argc, argv, short_opts, long_opt_start,
293                                   &index)) != EOF) {
294                 switch (opt) {
295                 case 'A':
296                         start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST;
297                         break;
298                 case 'c':
299                         if (optarg == NULL || strcmp(optarg, "on") == 0) {
300                                 start.ls_flags |= LPF_CREATE_OSTOBJ;
301                         } else if (strcmp(optarg, "off") != 0) {
302                                 fprintf(stderr, "invalid switch: -c '%s'. "
303                                         "valid switches are:\n"
304                                         "empty ('on'), or 'off' without space. "
305                                         "For example:\n"
306                                         "'-c', '-con', '-coff'\n", optarg);
307                                 return -EINVAL;
308                         }
309                         start.ls_valid |= LSV_CREATE_OSTOBJ;
310                         break;
311                 case 'C':
312                         if (optarg == NULL || strcmp(optarg, "on") == 0) {
313                                 start.ls_flags |= LPF_CREATE_MDTOBJ;
314                         } else if (strcmp(optarg, "off") != 0) {
315                                 fprintf(stderr, "invalid switch: -C '%s'. "
316                                         "valid switches are:\n"
317                                         "empty ('on'), or 'off' without space. "
318                                         "For example:\n"
319                                         "'-C', '-Con', '-Coff'\n", optarg);
320                                 return -EINVAL;
321                         }
322                         start.ls_valid |= LSV_CREATE_MDTOBJ;
323                         break;
324                 case 'd':
325                         if (optarg == NULL || strcmp(optarg, "on") == 0) {
326                                 start.ls_flags |= LPF_DELAY_CREATE_OSTOBJ;
327                         } else if (strcmp(optarg, "off") != 0) {
328                                 fprintf(stderr, "invalid switch: -c '%s'. "
329                                         "valid switches are:\n"
330                                         "empty ('on'), or 'off' without space. "
331                                         "For example:\n"
332                                         "'-c', '-con', '-coff'\n", optarg);
333                                 return -EINVAL;
334                         }
335                         start.ls_valid |= LSV_DELAY_CREATE_OSTOBJ;
336                         break;
337                 case 'e':
338                         if (strcmp(optarg, "abort") == 0) {
339                                 start.ls_flags |= LPF_FAILOUT;
340                         } else if (strcmp(optarg, "continue") != 0) {
341                                 fprintf(stderr, "invalid error mode: -e '%s'."
342                                         "valid modes are: "
343                                         "'continue' or 'abort'.\n", optarg);
344                                 return -EINVAL;
345                         }
346                         start.ls_valid |= LSV_ERROR_HANDLE;
347                         break;
348                 case 'h':
349                         usage_start();
350                         return 0;
351                 case 'M':
352                         rc = lfsck_pack_dev(&data, device, optarg);
353                         if (rc != 0)
354                                 return rc;
355                         break;
356                 case 'n':
357                         if (optarg == NULL || strcmp(optarg, "on") == 0) {
358                                 start.ls_flags |= LPF_DRYRUN;
359                         } else if (strcmp(optarg, "off") != 0) {
360                                 fprintf(stderr, "invalid switch: -n '%s'. "
361                                         "valid switches are:\n"
362                                         "empty ('on'), or 'off' without space. "
363                                         "For example:\n"
364                                         "'-n', '-non', '-noff'\n", optarg);
365                                 return -EINVAL;
366                         }
367                         start.ls_valid |= LSV_DRYRUN;
368                         break;
369                 case 'o':
370                         start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST |
371                                           LPF_OST_ORPHAN;
372                         break;
373                 case 'r':
374                         start.ls_flags |= LPF_RESET;
375                         break;
376                 case 's':
377                         val = atoi(optarg);
378                         start.ls_speed_limit = val;
379                         start.ls_valid |= LSV_SPEED_LIMIT;
380                         break;
381                 case 't': {
382                         char *typename;
383
384                         if (start.ls_active == LFSCK_TYPES_ALL)
385                                 start.ls_active = 0;
386                         while ((typename = strsep(&optarg, ",")) != NULL) {
387                                 enum lfsck_type type;
388
389                                 type = lfsck_name2type(typename);
390                                 if (type == -1)
391                                         goto bad_type;
392                                 start.ls_active |= type;
393                         }
394                         break;
395 bad_type:
396                         fprintf(stderr, "invalid check type -t '%s'. "
397                                 "valid types are:\n", typename);
398                         for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++)
399                                 fprintf(stderr, "%s%s", i != 0 ? "," : "",
400                                         lfsck_types_names[i].ltn_name);
401                         fprintf(stderr, "\n");
402                         return -EINVAL;
403                 }
404                 case 'w':
405                         val = atoi(optarg);
406                         if (val < 1 || val > LFSCK_ASYNC_WIN_MAX) {
407                                 fprintf(stderr,
408                                         "Invalid async window size that "
409                                         "may cause memory issues. The valid "
410                                         "range is [1 - %u].\n",
411                                         LFSCK_ASYNC_WIN_MAX);
412                                 return -EINVAL;
413                         }
414
415                         start.ls_async_windows = val;
416                         start.ls_valid |= LSV_ASYNC_WINDOWS;
417                         break;
418                 default:
419                         fprintf(stderr, "Invalid option, '-h' for help.\n");
420                         return -EINVAL;
421                 }
422         }
423
424         if (start.ls_active == LFSCK_TYPES_ALL)
425                 start.ls_active = LFSCK_TYPES_DEF;
426
427         if (data.ioc_inlbuf4 == NULL) {
428                 rc = lfsck_get_dev_name(&data, device, start.ls_active,
429                                         start.ls_flags & LPF_ALL_TGT);
430                 if (rc != 0)
431                         return rc;
432         }
433
434         data.ioc_inlbuf1 = (char *)&start;
435         data.ioc_inllen1 = sizeof(start);
436         memset(buf, 0, sizeof(rawbuf));
437         rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
438         if (rc != 0) {
439                 fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
440                 return rc;
441         }
442
443         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_START_LFSCK, buf);
444         if (rc < 0) {
445                 perror("Fail to start LFSCK");
446                 return rc;
447         }
448
449         obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
450         printf("Started LFSCK on the device %s: scrub", device);
451         for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) {
452                 if (start.ls_active & lfsck_types_names[i].ltn_type) {
453                         printf(" %s", lfsck_types_names[i].ltn_name);
454                         start.ls_active &= ~lfsck_types_names[i].ltn_type;
455                 }
456         }
457         if (start.ls_active != 0)
458                 printf(" unknown(0x%x)", start.ls_active);
459         printf("\n");
460
461         return 0;
462 }
463
464 int jt_lfsck_stop(int argc, char **argv)
465 {
466         struct obd_ioctl_data data;
467         char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
468         char device[MAX_OBD_NAME];
469         struct lfsck_stop stop;
470         char *short_opts = "AhM:";
471         int opt, index, rc;
472
473         memset(&data, 0, sizeof(data));
474         memset(&stop, 0, sizeof(stop));
475         memset(device, 0, MAX_OBD_NAME);
476
477         /* Reset the 'optind' for the case of getopt_long() called multiple
478          * times under the same lctl. */
479         optind = 0;
480         while ((opt = getopt_long(argc, argv, short_opts, long_opt_stop,
481                                   &index)) != EOF) {
482                 switch (opt) {
483                 case 'A':
484                         stop.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST;
485                         break;
486                 case 'h':
487                         usage_stop();
488                         return 0;
489                 case 'M':
490                         rc = lfsck_pack_dev(&data, device, optarg);
491                         if (rc != 0)
492                                 return rc;
493                         break;
494                 default:
495                         fprintf(stderr, "Invalid option, '-h' for help.\n");
496                         return -EINVAL;
497                 }
498         }
499
500         if (data.ioc_inlbuf4 == NULL) {
501                 rc = lfsck_get_dev_name(&data, device, 0,
502                                         stop.ls_flags & LPF_ALL_TGT);
503                 if (rc != 0)
504                         return rc;
505         }
506
507         data.ioc_inlbuf1 = (char *)&stop;
508         data.ioc_inllen1 = sizeof(stop);
509         memset(buf, 0, sizeof(rawbuf));
510         rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
511         if (rc != 0) {
512                 fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
513                 return rc;
514         }
515
516         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_STOP_LFSCK, buf);
517         if (rc < 0) {
518                 perror("Fail to stop LFSCK");
519                 return rc;
520         }
521
522         printf("Stopped LFSCK on the device %s.\n", device);
523         return 0;
524 }
525
526 int jt_lfsck_query(int argc, char **argv)
527 {
528         struct obd_ioctl_data data = { 0 };
529         char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
530         char device[MAX_OBD_NAME] = "";
531         struct lfsck_query query = { .lu_types = LFSCK_TYPES_ALL };
532         int opt, index, rc, i;
533         enum lfsck_type type;
534
535         while ((opt = getopt_long(argc, argv, "hM:t:w", long_opt_query,
536                                   &index)) != EOF) {
537                 switch (opt) {
538                 case 'h':
539                         usage_query();
540                         return 0;
541                 case 'M':
542                         rc = lfsck_pack_dev(&data, device, optarg);
543                         if (rc != 0)
544                                 return rc;
545                         break;
546                 case 't': {
547                         char *typename;
548
549                         if (query.lu_types == LFSCK_TYPES_ALL)
550                                 query.lu_types = 0;
551                         while ((typename = strsep(&optarg, ",")) != NULL) {
552                                 type = lfsck_name2type(typename);
553                                 if (type == -1)
554                                         goto bad_type;
555                                 query.lu_types |= type;
556                         }
557                         break;
558
559 bad_type:
560                         fprintf(stderr, "invalid LFSCK type -t '%s'. "
561                                 "valid types are:\n", typename);
562                         for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++)
563                                 fprintf(stderr, "%s%s", i != 0 ? "," : "",
564                                         lfsck_types_names[i].ltn_name);
565                         fprintf(stderr, "\n");
566                         return -EINVAL;
567                 }
568                 case 'w':
569                         query.lu_flags |= LPF_WAIT;
570                         break;
571                 default:
572                         fprintf(stderr, "Invalid option, '-h' for help.\n");
573                         usage_query();
574                         return -EINVAL;
575                 }
576         }
577
578         if (data.ioc_inlbuf4 == NULL) {
579                 rc = lfsck_get_dev_name(&data, device, 0, true);
580                 if (rc != 0)
581                         return rc;
582         }
583
584         data.ioc_inlbuf1 = (char *)&query;
585         data.ioc_inllen1 = sizeof(query);
586         memset(buf, 0, sizeof(rawbuf));
587         rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
588         if (rc != 0) {
589                 fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
590                 return rc;
591         }
592
593         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_QUERY_LFSCK, buf);
594         if (rc < 0) {
595                 perror("Fail to query LFSCK");
596                 return rc;
597         }
598
599         obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
600         for (i = 0, type = 1 << i; i < LFSCK_TYPE_BITS; i++, type = 1 << i) {
601                 const char *name;
602                 int j;
603
604                 if (!(query.lu_types & type))
605                         continue;
606
607                 name = lfsck_type2name(type);
608                 for (j = 0; j <= LS_MAX; j++)
609                         printf("%s_mdts_%s: %d\n", name,
610                                lfsck_status2name(j), query.lu_mdts_count[i][j]);
611
612                 for (j = 0; j <= LS_MAX; j++)
613                         printf("%s_osts_%s: %d\n", name,
614                                lfsck_status2name(j), query.lu_osts_count[i][j]);
615
616                 printf("%s_repaired: %llu\n", name, query.lu_repaired[i]);
617         }
618
619         return 0;
620 }