]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/scrub.c
xfs: non-scrub - remove unused function parameters
[thirdparty/xfsprogs-dev.git] / io / scrub.c
CommitLineData
813c67c7
DW
1/*
2 * Copyright (C) 2017 Oracle. All Rights Reserved.
3 *
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would 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 for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <sys/uio.h>
21#include <xfs/xfs.h>
22#include "command.h"
23#include "input.h"
24#include "init.h"
25#include "path.h"
26#include "io.h"
27
28static struct cmdinfo scrub_cmd;
29
30/* Type info and names for the scrub types. */
31enum scrub_type {
32 ST_NONE, /* disabled */
33 ST_PERAG, /* per-AG metadata */
34 ST_FS, /* per-FS metadata */
35 ST_INODE, /* per-inode metadata */
36};
37
38struct scrub_descr {
39 const char *name;
40 enum scrub_type type;
41};
42
43static const struct scrub_descr scrubbers[XFS_SCRUB_TYPE_NR] = {
44 [XFS_SCRUB_TYPE_PROBE] = {"probe", ST_NONE},
45 [XFS_SCRUB_TYPE_SB] = {"sb", ST_PERAG},
46 [XFS_SCRUB_TYPE_AGF] = {"agf", ST_PERAG},
47 [XFS_SCRUB_TYPE_AGFL] = {"agfl", ST_PERAG},
48 [XFS_SCRUB_TYPE_AGI] = {"agi", ST_PERAG},
49 [XFS_SCRUB_TYPE_BNOBT] = {"bnobt", ST_PERAG},
50 [XFS_SCRUB_TYPE_CNTBT] = {"cntbt", ST_PERAG},
51 [XFS_SCRUB_TYPE_INOBT] = {"inobt", ST_PERAG},
52 [XFS_SCRUB_TYPE_FINOBT] = {"finobt", ST_PERAG},
53 [XFS_SCRUB_TYPE_RMAPBT] = {"rmapbt", ST_PERAG},
54 [XFS_SCRUB_TYPE_REFCNTBT] = {"refcountbt", ST_PERAG},
55 [XFS_SCRUB_TYPE_INODE] = {"inode", ST_INODE},
56 [XFS_SCRUB_TYPE_BMBTD] = {"bmapbtd", ST_INODE},
57 [XFS_SCRUB_TYPE_BMBTA] = {"bmapbta", ST_INODE},
58 [XFS_SCRUB_TYPE_BMBTC] = {"bmapbtc", ST_INODE},
59 [XFS_SCRUB_TYPE_DIR] = {"directory", ST_INODE},
60 [XFS_SCRUB_TYPE_XATTR] = {"xattr", ST_INODE},
61 [XFS_SCRUB_TYPE_SYMLINK] = {"symlink", ST_INODE},
62 [XFS_SCRUB_TYPE_PARENT] = {"parent", ST_INODE},
63 [XFS_SCRUB_TYPE_RTBITMAP] = {"rtbitmap", ST_FS},
64 [XFS_SCRUB_TYPE_RTSUM] = {"rtsummary", ST_FS},
65 [XFS_SCRUB_TYPE_UQUOTA] = {"usrquota", ST_FS},
66 [XFS_SCRUB_TYPE_GQUOTA] = {"grpquota", ST_FS},
67 [XFS_SCRUB_TYPE_PQUOTA] = {"prjquota", ST_FS},
68};
69
70static void
71scrub_help(void)
72{
73 const struct scrub_descr *d;
74 int i;
75
76 printf(_(
77"\n"
78" Scrubs a piece of XFS filesystem metadata. The first argument is the type\n"
79" of metadata to examine. Allocation group metadata types take one AG number\n"
80" as the second parameter. Inode metadata types act on the currently open file\n"
81" or (optionally) take an inode number and generation number to act upon as\n"
82" the second and third parameters.\n"
83"\n"
84" Example:\n"
85" 'scrub inobt 3' - scrub the inode btree in AG 3.\n"
86" 'scrub bmapbtd 128 13525' - scrubs the extent map of inode 128 gen 13525.\n"
87"\n"
88" Known metadata scrub types are:"));
89 for (i = 0, d = scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++)
90 printf(" %s", d->name);
91 printf("\n");
92}
93
94static void
95scrub_ioctl(
96 int fd,
97 int type,
98 uint64_t control,
99 uint32_t control2)
100{
101 struct xfs_scrub_metadata meta;
102 const struct scrub_descr *sc;
103 int error;
104
105 sc = &scrubbers[type];
106 memset(&meta, 0, sizeof(meta));
107 meta.sm_type = type;
108 switch (sc->type) {
109 case ST_PERAG:
110 meta.sm_agno = control;
111 break;
112 case ST_INODE:
113 meta.sm_ino = control;
114 meta.sm_gen = control2;
115 break;
116 case ST_NONE:
117 case ST_FS:
118 /* no control parameters */
119 break;
120 }
121 meta.sm_flags = 0;
122
123 error = ioctl(fd, XFS_IOC_SCRUB_METADATA, &meta);
124 if (error)
125 perror("scrub");
126 if (meta.sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
127 printf(_("Corruption detected.\n"));
128 if (meta.sm_flags & XFS_SCRUB_OFLAG_PREEN)
129 printf(_("Optimization possible.\n"));
130 if (meta.sm_flags & XFS_SCRUB_OFLAG_XFAIL)
131 printf(_("Cross-referencing failed.\n"));
132 if (meta.sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
133 printf(_("Corruption detected during cross-referencing.\n"));
134 if (meta.sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
135 printf(_("Scan was not complete.\n"));
136}
137
138static int
139parse_args(
140 int argc,
141 char **argv,
142 struct cmdinfo *cmdinfo,
143 void (*fn)(int, int, uint64_t, uint32_t))
144{
145 char *p;
146 int type = -1;
147 int i, c;
148 uint64_t control = 0;
149 uint32_t control2 = 0;
150 const struct scrub_descr *d = NULL;
151
152 while ((c = getopt(argc, argv, "")) != EOF) {
153 switch (c) {
154 default:
155 return command_usage(cmdinfo);
156 }
157 }
158 if (optind > argc - 1)
159 return command_usage(cmdinfo);
160
161 for (i = 0, d = scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++) {
162 if (strcmp(d->name, argv[optind]) == 0) {
163 type = i;
164 break;
165 }
166 }
167 optind++;
168
169 if (type < 0) {
170 printf(_("Unknown type '%s'.\n"), argv[optind]);
171 return command_usage(cmdinfo);
172 }
173
174 switch (d->type) {
175 case ST_INODE:
176 if (optind == argc) {
177 control = 0;
178 control2 = 0;
179 } else if (optind == argc - 2) {
180 control = strtoull(argv[optind], &p, 0);
181 if (*p != '\0') {
182 fprintf(stderr,
183 _("Bad inode number '%s'.\n"),
184 argv[optind]);
185 return 0;
186 }
187 control2 = strtoul(argv[optind + 1], &p, 0);
188 if (*p != '\0') {
189 fprintf(stderr,
190 _("Bad generation number '%s'.\n"),
191 argv[optind + 1]);
192 return 0;
193 }
194 } else {
195 fprintf(stderr,
196 _("Must specify inode number and generation.\n"));
197 return 0;
198 }
199 break;
200 case ST_PERAG:
201 if (optind != argc - 1) {
202 fprintf(stderr,
203 _("Must specify one AG number.\n"));
204 return 0;
205 }
206 control = strtoul(argv[optind], &p, 0);
207 if (*p != '\0') {
208 fprintf(stderr,
209 _("Bad AG number '%s'.\n"), argv[optind]);
210 return 0;
211 }
212 break;
213 case ST_FS:
214 case ST_NONE:
215 if (optind != argc) {
216 fprintf(stderr,
217 _("No parameters allowed.\n"));
218 return 0;
219 }
220 break;
221 default:
222 ASSERT(0);
223 break;
224 }
225 fn(file->fd, type, control, control2);
226
227 return 0;
228}
229
230static int
231scrub_f(
232 int argc,
233 char **argv)
234{
235 return parse_args(argc, argv, &scrub_cmd, scrub_ioctl);
236}
237
238void
239scrub_init(void)
240{
241 scrub_cmd.name = "scrub";
242 scrub_cmd.altname = "sc";
243 scrub_cmd.cfunc = scrub_f;
244 scrub_cmd.argmin = 1;
245 scrub_cmd.argmax = -1;
246 scrub_cmd.flags = CMD_NOMAP_OK;
247 scrub_cmd.args = _("type [agno|ino gen]");
248 scrub_cmd.oneline = _("scrubs filesystem metadata");
249 scrub_cmd.help = scrub_help;
250
251 add_command(&scrub_cmd);
252}