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