]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/parent.c
xfs: non-scrub - remove unused function parameters
[thirdparty/xfsprogs-dev.git] / io / parent.c
CommitLineData
258b00ea 1/*
74043ab2 2 * Copyright (c) 2005-2006 Silicon Graphics, Inc.
258b00ea
TS
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
6b803e5a
CH
19#include "command.h"
20#include "input.h"
21#include "path.h"
22#include "parent.h"
23#include "handle.h"
24#include "jdm.h"
258b00ea
TS
25#include "init.h"
26#include "io.h"
27
28#define PARENTBUF_SZ 16384
74043ab2 29#define BSTATBUF_SZ 16384
258b00ea
TS
30
31static cmdinfo_t parent_cmd;
32static int verbose_flag;
33static int err_status;
74043ab2
TS
34static __u64 inodes_checked;
35static char *mntpt;
258b00ea
TS
36
37/*
38 * check out a parent entry to see if the values seem valid
39 */
40static void
74043ab2 41check_parent_entry(xfs_bstat_t *bstatp, parent_t *parent)
258b00ea
TS
42{
43 int sts;
44 char fullpath[PATH_MAX];
45 struct stat statbuf;
46 char *str;
47
48 sprintf(fullpath, _("%s%s"), mntpt, parent->p_name);
49
50 sts = lstat(fullpath, &statbuf);
51 if (sts != 0) {
52 fprintf(stderr,
74043ab2 53 _("inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n"),
f934f4a5 54 (unsigned long long) bstatp->bs_ino, fullpath);
258b00ea
TS
55 if (verbose_flag) {
56 fprintf(stderr,
57 _("path \"%s\" does not stat for inode: %llu; err = %s\n"),
58 fullpath,
f934f4a5 59 (unsigned long long) bstatp->bs_ino,
258b00ea
TS
60 strerror(errno));
61 }
62 err_status++;
63 return;
64 } else {
65 if (verbose_flag > 1) {
66 printf(_("path \"%s\" found\n"), fullpath);
67 }
68 }
69
70 if (statbuf.st_ino != bstatp->bs_ino) {
71 fprintf(stderr,
72 _("inode-path for inode: %llu is incorrect - wrong inode#\n"),
f934f4a5 73 (unsigned long long) bstatp->bs_ino);
258b00ea
TS
74 if (verbose_flag) {
75 fprintf(stderr,
76 _("ino mismatch for path \"%s\" %llu vs %llu\n"),
77 fullpath,
5acc4dfe
NS
78 (unsigned long long)statbuf.st_ino,
79 (unsigned long long)bstatp->bs_ino);
258b00ea
TS
80 }
81 err_status++;
82 return;
83 } else if (verbose_flag > 1) {
5acc4dfe
NS
84 printf(_("inode number match: %llu\n"),
85 (unsigned long long)statbuf.st_ino);
258b00ea
TS
86 }
87
88 /* get parent path */
89 str = strrchr(fullpath, '/');
90 *str = '\0';
91 sts = stat(fullpath, &statbuf);
92 if (sts != 0) {
93 fprintf(stderr,
94 _("parent path \"%s\" does not stat: %s\n"),
95 fullpath,
96 strerror(errno));
97 err_status++;
98 return;
99 } else {
100 if (parent->p_ino != statbuf.st_ino) {
101 fprintf(stderr,
102 _("inode-path for inode: %llu is incorrect - wrong parent inode#\n"),
f934f4a5 103 (unsigned long long) bstatp->bs_ino);
258b00ea
TS
104 if (verbose_flag) {
105 fprintf(stderr,
106 _("ino mismatch for path \"%s\" %llu vs %llu\n"),
107 fullpath,
5acc4dfe
NS
108 (unsigned long long)parent->p_ino,
109 (unsigned long long)statbuf.st_ino);
258b00ea
TS
110 }
111 err_status++;
112 return;
113 } else {
114 if (verbose_flag > 1) {
f934f4a5
AE
115 printf(_("parent ino match for %llu\n"),
116 (unsigned long long) parent->p_ino);
258b00ea
TS
117 }
118 }
119 }
120}
121
122static void
74043ab2
TS
123check_parents(parent_t *parentbuf, size_t *parentbuf_size,
124 jdm_fshandle_t *fshandlep, xfs_bstat_t *statp)
258b00ea
TS
125{
126 int error, i;
74043ab2 127 __u32 count;
258b00ea 128 parent_t *entryp;
258b00ea 129
258b00ea 130 do {
74043ab2
TS
131 error = jdm_parentpaths(fshandlep, statp, parentbuf, *parentbuf_size, &count);
132
133 if (error == ERANGE) {
134 *parentbuf_size *= 2;
135 parentbuf = (parent_t *)realloc(parentbuf, *parentbuf_size);
136 } else if (error) {
137 fprintf(stderr, _("parentpaths failed for ino %llu: %s\n"),
f934f4a5 138 (unsigned long long) statp->bs_ino,
8577b2c9 139 strerror(errno));
258b00ea
TS
140 err_status++;
141 break;
142 }
74043ab2 143 } while (error == ERANGE);
f8149110 144
258b00ea 145
74043ab2
TS
146 if (count == 0) {
147 /* no links for inode - something wrong here */
f934f4a5
AE
148 fprintf(stderr, _("inode-path for inode: %llu is missing\n"),
149 (unsigned long long) statp->bs_ino);
74043ab2
TS
150 err_status++;
151 }
258b00ea 152
74043ab2
TS
153 entryp = parentbuf;
154 for (i = 0; i < count; i++) {
155 check_parent_entry(statp, entryp);
156 entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
157 }
258b00ea
TS
158}
159
160static int
74043ab2
TS
161do_bulkstat(parent_t *parentbuf, size_t *parentbuf_size, xfs_bstat_t *bstatbuf,
162 int fsfd, jdm_fshandle_t *fshandlep)
258b00ea 163{
d026b19e
NS
164 __s32 buflenout;
165 __u64 lastino = 0;
258b00ea
TS
166 xfs_bstat_t *p;
167 xfs_bstat_t *endp;
168 xfs_fsop_bulkreq_t bulkreq;
169 struct stat mntstat;
170
a504bf72 171 if (stat(mntpt, &mntstat)) {
258b00ea 172 fprintf(stderr, _("can't stat mount point \"%s\": %s\n"),
8577b2c9 173 mntpt, strerror(errno));
258b00ea
TS
174 return 1;
175 }
176
177 bulkreq.lastip = &lastino;
178 bulkreq.icount = BSTATBUF_SZ;
179 bulkreq.ubuffer = (void *)bstatbuf;
180 bulkreq.ocount = &buflenout;
181
182 while (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) == 0) {
183 if (*(bulkreq.ocount) == 0) {
184 return 0;
185 }
186 for (p = bstatbuf, endp = bstatbuf + *bulkreq.ocount; p < endp; p++) {
187
188 /* inode being modified, get synced data with iget */
189 if ( (!p->bs_nlink || !p->bs_mode) && p->bs_ino != 0 ) {
190
191 if (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq) < 0) {
192 fprintf(stderr,
193 _("failed to get bulkstat information for inode %llu\n"),
f934f4a5 194 (unsigned long long) p->bs_ino);
258b00ea
TS
195 continue;
196 }
197 if (!p->bs_nlink || !p->bs_mode || !p->bs_ino) {
198 fprintf(stderr,
199 _("failed to get valid bulkstat information for inode %llu\n"),
f934f4a5 200 (unsigned long long) p->bs_ino);
258b00ea
TS
201 continue;
202 }
203 }
204
205 /* skip root */
206 if (p->bs_ino == mntstat.st_ino) {
207 continue;
208 }
209
210 if (verbose_flag > 1) {
f934f4a5
AE
211 printf(_("checking inode %llu\n"),
212 (unsigned long long) p->bs_ino);
258b00ea
TS
213 }
214
215 /* print dotted progress */
216 if ((inodes_checked % 100) == 0 && verbose_flag == 1) {
217 printf("."); fflush(stdout);
218 }
219 inodes_checked++;
220
74043ab2 221 check_parents(parentbuf, parentbuf_size, fshandlep, p);
258b00ea
TS
222 }
223
224 }/*while*/
225
226 fprintf(stderr, _("syssgi bulkstat failed: %s\n"), strerror(errno));
227 return 1;
228}
229
230static int
231parent_check(void)
232{
258b00ea
TS
233 int fsfd;
234 jdm_fshandle_t *fshandlep;
235 parent_t *parentbuf;
74043ab2 236 size_t parentbuf_size = PARENTBUF_SZ;
258b00ea
TS
237 xfs_bstat_t *bstatbuf;
238
239 err_status = 0;
240 inodes_checked = 0;
241
242 sync();
243
258b00ea
TS
244 fsfd = file->fd;
245
246 fshandlep = jdm_getfshandle(mntpt);
5e656dbb 247 if (fshandlep == NULL) {
258b00ea
TS
248 fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"),
249 mntpt,
250 strerror(errno));
251 return 1;
252 }
253
254 /* allocate buffers */
255 bstatbuf = (xfs_bstat_t *)calloc(BSTATBUF_SZ, sizeof(xfs_bstat_t));
74043ab2 256 parentbuf = (parent_t *)malloc(parentbuf_size);
258b00ea
TS
257 if (!bstatbuf || !parentbuf) {
258 fprintf(stderr, _("unable to allocate buffers: %s\n"),
259 strerror(errno));
713ba3f2
ES
260 err_status = 1;
261 goto out;
258b00ea
TS
262 }
263
74043ab2 264 if (do_bulkstat(parentbuf, &parentbuf_size, bstatbuf, fsfd, fshandlep) != 0)
258b00ea
TS
265 err_status++;
266
267 if (err_status > 0)
268 fprintf(stderr, _("num errors: %d\n"), err_status);
269 else
f934f4a5
AE
270 printf(_("succeeded checking %llu inodes\n"),
271 (unsigned long long) inodes_checked);
258b00ea 272
713ba3f2 273out:
258b00ea
TS
274 free(bstatbuf);
275 free(parentbuf);
713ba3f2 276 free(fshandlep);
258b00ea
TS
277 return err_status;
278}
279
280static void
74043ab2 281print_parent_entry(parent_t *parent, int fullpath)
258b00ea 282{
f934f4a5 283 printf(_("p_ino = %llu\n"), (unsigned long long) parent->p_ino);
258b00ea
TS
284 printf(_("p_gen = %u\n"), parent->p_gen);
285 printf(_("p_reclen = %u\n"), parent->p_reclen);
74043ab2
TS
286 if (fullpath)
287 printf(_("p_name = \"%s%s\"\n"), mntpt, parent->p_name);
288 else
289 printf(_("p_name = \"%s\"\n"), parent->p_name);
258b00ea
TS
290}
291
292static int
293parent_list(int fullpath)
294{
70ac12f8 295 void *handlep = NULL;
258b00ea
TS
296 size_t handlen;
297 int error, i;
298 int retval = 1;
74043ab2 299 __u32 count;
258b00ea 300 parent_t *entryp;
74043ab2 301 parent_t *parentbuf = NULL;
258b00ea 302 char *path = file->name;
74043ab2 303 int pb_size = PARENTBUF_SZ;
258b00ea
TS
304
305 /* XXXX for linux libhandle version - to set libhandle fsfd cache */
306 {
307 void *fshandle;
308 size_t fshlen;
309
74043ab2 310 if (path_to_fshandle(mntpt, &fshandle, &fshlen) != 0) {
258b00ea
TS
311 fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"),
312 progname, path, strerror(errno));
313 goto error;
314 }
70ac12f8 315 free_handle(fshandle, fshlen);
258b00ea
TS
316 }
317
318 if (path_to_handle(path, &handlep, &handlen) != 0) {
319 fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path);
320 goto error;
321 }
322
258b00ea 323 do {
74043ab2
TS
324 parentbuf = (parent_t *)realloc(parentbuf, pb_size);
325 if (!parentbuf) {
326 fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"),
327 progname, strerror(errno));
70ac12f8 328 goto error;
74043ab2
TS
329 }
330
258b00ea 331 if (fullpath) {
74043ab2 332 error = parentpaths_by_handle(handlep,
258b00ea
TS
333 handlen,
334 parentbuf,
74043ab2
TS
335 pb_size,
336 &count);
258b00ea 337 } else {
74043ab2 338 error = parents_by_handle(handlep,
258b00ea
TS
339 handlen,
340 parentbuf,
74043ab2
TS
341 pb_size,
342 &count);
258b00ea 343 }
74043ab2
TS
344 if (error == ERANGE) {
345 pb_size *= 2;
346 } else if (error) {
347 fprintf(stderr, _("%s: %s call failed for \"%s\": %s\n"),
348 progname, fullpath ? "parentpaths" : "parents",
349 path, strerror(errno));
258b00ea
TS
350 goto error;
351 }
74043ab2 352 } while (error == ERANGE);
258b00ea 353
74043ab2
TS
354 if (count == 0) {
355 /* no links for inode - something wrong here */
356 fprintf(stderr, _("%s: inode-path is missing\n"), progname);
357 goto error;
358 }
258b00ea 359
74043ab2
TS
360 entryp = parentbuf;
361 for (i = 0; i < count; i++) {
362 print_parent_entry(entryp, fullpath);
363 entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
364 }
258b00ea
TS
365
366 retval = 0;
367error:
70ac12f8 368 free(handlep);
258b00ea
TS
369 free(parentbuf);
370 return retval;
371}
372
373int
374parent_f(int argc, char **argv)
375{
376 int c;
377 int listpath_flag = 0;
378 int check_flag = 0;
74043ab2
TS
379 fs_path_t *fs;
380 static int tab_init;
381
382 if (!tab_init) {
383 tab_init = 1;
0900efe4 384 fs_table_initialise(0, NULL, 0, NULL);
74043ab2
TS
385 }
386 fs = fs_table_lookup(file->name, FS_MOUNT_POINT);
387 if (!fs) {
388 fprintf(stderr, _("file argument, \"%s\", is not in a mounted XFS filesystem\n"),
389 file->name);
390 return 1;
391 }
392 mntpt = fs->fs_dir;
258b00ea
TS
393
394 verbose_flag = 0;
395
396 while ((c = getopt(argc, argv, "cpv")) != EOF) {
397 switch (c) {
398 case 'c':
399 check_flag = 1;
400 break;
401 case 'p':
402 listpath_flag = 1;
403 break;
404 case 'v':
405 verbose_flag++;
406 break;
407 default:
408 return command_usage(&parent_cmd);
409 }
410 }
411
412 if (!check_flag && !listpath_flag) /* default case */
413 exitcode = parent_list(listpath_flag);
414 else {
415 if (listpath_flag)
416 exitcode = parent_list(listpath_flag);
417 if (check_flag)
418 exitcode = parent_check();
419 }
420
421 return 0;
422}
423
424static void
425parent_help(void)
426{
427 printf(_(
428"\n"
429" list the current file's parents and their filenames\n"
430"\n"
431" -c -- check the current file's file system for parent consistency\n"
432" -p -- list the current file's parents and their full paths\n"
433" -v -- verbose mode\n"
434"\n"));
435}
436
437void
438parent_init(void)
439{
ad765595 440 parent_cmd.name = "parent";
258b00ea
TS
441 parent_cmd.cfunc = parent_f;
442 parent_cmd.argmin = 0;
443 parent_cmd.argmax = -1;
444 parent_cmd.args = _("[-cpv]");
445 parent_cmd.flags = CMD_NOMAP_OK;
446 parent_cmd.oneline = _("print or check parent inodes");
447 parent_cmd.help = parent_help;
448
449 if (expert)
450 add_command(&parent_cmd);
451}