2
* Copyright (c) 2005 Silicon Graphics, Inc.
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.
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.
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
20
#include <xfs/command.h>
21
#include <xfs/input.h>
23
#include <xfs/parent.h>
24
#include <xfs/handle.h>
29
#define PARENTBUF_SZ 16384
30
#define BSTATBUF_SZ 4096
32
static cmdinfo_t parent_cmd;
33
static int verbose_flag;
34
static int err_status;
35
static uint64_t inodes_checked;
38
* check out a parent entry to see if the values seem valid
41
check_parent_entry(xfs_bstat_t *bstatp, parent_t *parent, char *mntpt)
44
char fullpath[PATH_MAX];
48
sprintf(fullpath, _("%s%s"), mntpt, parent->p_name);
50
sts = lstat(fullpath, &statbuf);
53
_("inode-path for inode: %llu is incorrect - path non-existent\n"),
57
_("path \"%s\" does not stat for inode: %llu; err = %s\n"),
65
if (verbose_flag > 1) {
66
printf(_("path \"%s\" found\n"), fullpath);
70
if (statbuf.st_ino != bstatp->bs_ino) {
72
_("inode-path for inode: %llu is incorrect - wrong inode#\n"),
76
_("ino mismatch for path \"%s\" %llu vs %llu\n"),
83
} else if (verbose_flag > 1) {
84
printf(_("inode number match: %llu\n"), statbuf.st_ino);
88
str = strrchr(fullpath, '/');
90
sts = stat(fullpath, &statbuf);
93
_("parent path \"%s\" does not stat: %s\n"),
99
if (parent->p_ino != statbuf.st_ino) {
101
_("inode-path for inode: %llu is incorrect - wrong parent inode#\n"),
105
_("ino mismatch for path \"%s\" %llu vs %llu\n"),
113
if (verbose_flag > 1) {
114
printf(_("parent ino match for %llu\n"), parent->p_ino);
121
check_parents(parent_t *parentbuf, jdm_fshandle_t *fshandlep, xfs_bstat_t *statp, char *mntpt)
126
parent_cursor_t cursor;
128
memset(&cursor, 0, sizeof(cursor));
130
error = jdm_getparentpaths(fshandlep,
139
fprintf(stderr, _("getparentpaths failed for ino %llu: %s\n"),
147
/* no links for inode - something wrong here */
148
fprintf(stderr, _("inode-path for inode: %llu is missing\n"), statp->bs_ino);
154
for (i = 0; i < count; i++) {
155
check_parent_entry(statp, entryp, mntpt);
156
entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
163
do_bulkstat(parent_t *parentbuf, xfs_bstat_t *bstatbuf,
164
char *mntpt, int fsfd, jdm_fshandle_t *fshandlep)
171
xfs_fsop_bulkreq_t bulkreq;
174
if ((error = stat(mntpt, &mntstat))) {
175
fprintf(stderr, _("can't stat mount point \"%s\": %s\n"),
176
mntpt, strerror(error));
180
bulkreq.lastip = &lastino;
181
bulkreq.icount = BSTATBUF_SZ;
182
bulkreq.ubuffer = (void *)bstatbuf;
183
bulkreq.ocount = &buflenout;
185
while (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) == 0) {
186
if (*(bulkreq.ocount) == 0) {
189
for (p = bstatbuf, endp = bstatbuf + *bulkreq.ocount; p < endp; p++) {
191
/* inode being modified, get synced data with iget */
192
if ( (!p->bs_nlink || !p->bs_mode) && p->bs_ino != 0 ) {
194
if (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq) < 0) {
196
_("failed to get bulkstat information for inode %llu\n"),
200
if (!p->bs_nlink || !p->bs_mode || !p->bs_ino) {
202
_("failed to get valid bulkstat information for inode %llu\n"),
209
if (p->bs_ino == mntstat.st_ino) {
213
if (verbose_flag > 1) {
214
printf(_("checking inode %llu\n"), p->bs_ino);
217
/* print dotted progress */
218
if ((inodes_checked % 100) == 0 && verbose_flag == 1) {
219
printf("."); fflush(stdout);
223
check_parents(parentbuf, fshandlep, p, mntpt);
228
fprintf(stderr, _("syssgi bulkstat failed: %s\n"), strerror(errno));
239
jdm_fshandle_t *fshandlep;
241
xfs_bstat_t *bstatbuf;
250
fs_table_initialise();
252
fs = fs_table_lookup(file->name, FS_MOUNT_POINT);
254
fprintf(stderr, _("file argument, \"%s\", is not in a mounted XFS filesystem\n"),
261
fshandlep = jdm_getfshandle(mntpt);
262
if (fshandlep == 0) {
263
fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"),
269
/* allocate buffers */
270
bstatbuf = (xfs_bstat_t *)calloc(BSTATBUF_SZ, sizeof(xfs_bstat_t));
271
parentbuf = (parent_t *)malloc(PARENTBUF_SZ);
272
if (!bstatbuf || !parentbuf) {
273
fprintf(stderr, _("unable to allocate buffers: %s\n"),
278
if (do_bulkstat(parentbuf, bstatbuf, mntpt, fsfd, fshandlep) != 0)
282
fprintf(stderr, _("num errors: %d\n"), err_status);
284
printf(_("succeeded checking %llu inodes\n"), inodes_checked);
292
print_parent_entry(parent_t *parent)
294
printf(_("p_ino = %llu\n"), parent->p_ino);
295
printf(_("p_gen = %u\n"), parent->p_gen);
296
printf(_("p_reclen = %u\n"), parent->p_reclen);
297
printf(_("p_name = \"%s\"\n"),parent->p_name);
301
parent_list(int fullpath)
309
parent_cursor_t cursor;
311
char *path = file->name;
313
parentbuf = (parent_t *)malloc(PARENTBUF_SZ);
315
fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"),
316
progname, strerror(errno));
320
/* XXXX for linux libhandle version - to set libhandle fsfd cache */
325
if (path_to_fshandle(path, &fshandle, &fshlen) != 0) {
326
fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"),
327
progname, path, strerror(errno));
332
if (path_to_handle(path, &handlep, &handlen) != 0) {
333
fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path);
337
memset(&cursor, 0, sizeof(cursor));
340
error = getparentpaths_by_handle(handlep,
348
error = getparents_by_handle(handlep,
358
fprintf(stderr, _("%s: getparentpaths failed for \"%s\": %s\n"),
359
progname, path, strerror(errno));
364
/* no links for inode - something wrong here */
365
fprintf(stderr, _("%s: inode-path is missing\n"), progname);
370
for (i = 0; i < count; i++) {
371
print_parent_entry(entryp);
372
entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
384
parent_f(int argc, char **argv)
387
int listpath_flag = 0;
392
while ((c = getopt(argc, argv, "cpv")) != EOF) {
404
return command_usage(&parent_cmd);
408
if (!check_flag && !listpath_flag) /* default case */
409
exitcode = parent_list(listpath_flag);
412
exitcode = parent_list(listpath_flag);
414
exitcode = parent_check();
425
" list the current file's parents and their filenames\n"
427
" -c -- check the current file's file system for parent consistency\n"
428
" -p -- list the current file's parents and their full paths\n"
429
" -v -- verbose mode\n"
436
parent_cmd.name = _("parent");
437
parent_cmd.cfunc = parent_f;
438
parent_cmd.argmin = 0;
439
parent_cmd.argmax = -1;
440
parent_cmd.args = _("[-cpv]");
441
parent_cmd.flags = CMD_NOMAP_OK;
442
parent_cmd.oneline = _("print or check parent inodes");
443
parent_cmd.help = parent_help;
446
add_command(&parent_cmd);