blob: b7faa63941ecbbad2ba61423aa1f370422f4978f [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * ncheck.c --- given a list of inodes, generate a list of names
Theodore Ts'oefc6f622008-08-27 23:07:54 -04003 *
Theodore Ts'o3839e651997-04-26 13:21:57 +00004 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
6 */
7
8#include <stdio.h>
9#include <unistd.h>
10#include <stdlib.h>
11#include <ctype.h>
12#include <string.h>
13#include <time.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000014#ifdef HAVE_ERRNO_H
15#include <errno.h>
16#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000017#include <sys/types.h>
JP Abgralle0ed7402014-03-19 19:08:39 -070018#ifdef HAVE_GETOPT_H
19#include <getopt.h>
20#else
21extern int optind;
22extern char *optarg;
23#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000024
25#include "debugfs.h"
26
Theodore Ts'o3839e651997-04-26 13:21:57 +000027struct inode_walk_struct {
JP Abgralle0ed7402014-03-19 19:08:39 -070028 ext2_ino_t dir;
Theodore Ts'o03206bd2008-10-01 19:14:06 -040029 ext2_ino_t *iarray;
Theodore Ts'o3839e651997-04-26 13:21:57 +000030 int inodes_left;
31 int num_inodes;
32 int position;
Theodore Ts'oa25f0e72008-10-10 14:53:09 -040033 char *parent;
JP Abgralle0ed7402014-03-19 19:08:39 -070034 unsigned int get_pathname_failed:1;
35 unsigned int check_dirent:1;
Theodore Ts'o3839e651997-04-26 13:21:57 +000036};
37
Theodore Ts'o50e1e101997-04-26 13:58:21 +000038static int ncheck_proc(struct ext2_dir_entry *dirent,
Theodore Ts'o54434922003-12-07 01:28:50 -050039 int offset EXT2FS_ATTR((unused)),
40 int blocksize EXT2FS_ATTR((unused)),
41 char *buf EXT2FS_ATTR((unused)),
Theodore Ts'o50e1e101997-04-26 13:58:21 +000042 void *private)
Theodore Ts'o3839e651997-04-26 13:21:57 +000043{
44 struct inode_walk_struct *iw = (struct inode_walk_struct *) private;
JP Abgralle0ed7402014-03-19 19:08:39 -070045 struct ext2_inode inode;
46 errcode_t retval;
47 int filetype = dirent->name_len >> 8;
48 int i;
Theodore Ts'o3839e651997-04-26 13:21:57 +000049
50 iw->position++;
51 if (iw->position <= 2)
52 return 0;
53 for (i=0; i < iw->num_inodes; i++) {
Theodore Ts'o03206bd2008-10-01 19:14:06 -040054 if (iw->iarray[i] == dirent->inode) {
JP Abgralle0ed7402014-03-19 19:08:39 -070055 if (!iw->parent && !iw->get_pathname_failed) {
56 retval = ext2fs_get_pathname(current_fs,
57 iw->dir,
58 0, &iw->parent);
59 if (retval) {
60 com_err("ncheck", retval,
61 "while calling ext2fs_get_pathname for inode #%u", iw->dir);
62 iw->get_pathname_failed = 1;
63 }
64 }
65 if (iw->parent)
66 printf("%u\t%s/%.*s", iw->iarray[i],
67 iw->parent,
68 (dirent->name_len & 0xFF), dirent->name);
69 else
70 printf("%u\t<%u>/%.*s", iw->iarray[i],
71 iw->dir,
72 (dirent->name_len & 0xFF), dirent->name);
73 if (iw->check_dirent && filetype) {
74 if (!debugfs_read_inode(dirent->inode, &inode,
75 "ncheck") &&
76 filetype != ext2_file_type(inode.i_mode)) {
77 printf(" <--- BAD FILETYPE");
78 }
79 }
80 putc('\n', stdout);
Theodore Ts'o3839e651997-04-26 13:21:57 +000081 }
82 }
83 if (!iw->inodes_left)
84 return DIRENT_ABORT;
Theodore Ts'oefc6f622008-08-27 23:07:54 -040085
Theodore Ts'o3839e651997-04-26 13:21:57 +000086 return 0;
87}
88
89void do_ncheck(int argc, char **argv)
90{
91 struct inode_walk_struct iw;
JP Abgralle0ed7402014-03-19 19:08:39 -070092 int c, i;
Theodore Ts'o3839e651997-04-26 13:21:57 +000093 ext2_inode_scan scan = 0;
Theodore Ts'ob044c2e2001-01-11 15:26:39 +000094 ext2_ino_t ino;
Theodore Ts'o3839e651997-04-26 13:21:57 +000095 struct ext2_inode inode;
96 errcode_t retval;
97 char *tmp;
Theodore Ts'oefc6f622008-08-27 23:07:54 -040098
JP Abgralle0ed7402014-03-19 19:08:39 -070099 iw.check_dirent = 0;
100
101 reset_getopt();
102 while ((c = getopt (argc, argv, "c")) != EOF) {
103 switch (c) {
104 case 'c':
105 iw.check_dirent = 1;
106 break;
107 default:
108 goto print_usage;
109 }
110 }
111 argc -= optind;
112 argv += optind;
113
114 if (argc < 1) {
115 print_usage:
116 com_err(argv[0], 0, "Usage: ncheck [-c] <inode number> ...");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000117 return;
118 }
119 if (check_fs_open(argv[0]))
120 return;
121
Theodore Ts'o03206bd2008-10-01 19:14:06 -0400122 iw.iarray = malloc(sizeof(ext2_ino_t) * argc);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000123 if (!iw.iarray) {
Manish Katiyar87dd5692008-09-03 11:23:53 +0530124 com_err("ncheck", ENOMEM,
JP Abgralle0ed7402014-03-19 19:08:39 -0700125 "while allocating inode number array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000126 return;
127 }
Theodore Ts'o03206bd2008-10-01 19:14:06 -0400128 memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000129
JP Abgralle0ed7402014-03-19 19:08:39 -0700130 for (i=0; i < argc; i++) {
131 iw.iarray[i] = strtol(argv[i], &tmp, 0);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000132 if (*tmp) {
133 com_err(argv[0], 0, "Bad inode - %s", argv[i]);
Manish Katiyar87dd5692008-09-03 11:23:53 +0530134 goto error_out;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000135 }
136 }
137
JP Abgralle0ed7402014-03-19 19:08:39 -0700138 iw.num_inodes = iw.inodes_left = argc;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000139
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000140 retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000141 if (retval) {
142 com_err("ncheck", retval, "while opening inode scan");
143 goto error_out;
144 }
145
Theodore Ts'o643efb81999-11-08 19:27:13 +0000146 do {
147 retval = ext2fs_get_next_inode(scan, &ino, &inode);
148 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000149 if (retval) {
150 com_err("ncheck", retval, "while starting inode scan");
151 goto error_out;
152 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400153
Theodore Ts'o03206bd2008-10-01 19:14:06 -0400154 printf("Inode\tPathname\n");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000155 while (ino) {
156 if (!inode.i_links_count)
157 goto next;
158 /*
159 * To handle filesystems touched by 0.3c extfs; can be
160 * removed later.
161 */
162 if (inode.i_dtime)
163 goto next;
164 /* Ignore anything that isn't a directory */
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000165 if (!LINUX_S_ISDIR(inode.i_mode))
Theodore Ts'o3839e651997-04-26 13:21:57 +0000166 goto next;
167
168 iw.position = 0;
JP Abgralle0ed7402014-03-19 19:08:39 -0700169 iw.parent = 0;
170 iw.dir = ino;
171 iw.get_pathname_failed = 0;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400172
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000173 retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000174 ncheck_proc, &iw);
Theodore Ts'oa25f0e72008-10-10 14:53:09 -0400175 ext2fs_free_mem(&iw.parent);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000176 if (retval) {
177 com_err("ncheck", retval,
178 "while calling ext2_dir_iterate");
179 goto next;
180 }
181
182 if (iw.inodes_left == 0)
183 break;
184
185 next:
Theodore Ts'o643efb81999-11-08 19:27:13 +0000186 do {
187 retval = ext2fs_get_next_inode(scan, &ino, &inode);
188 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
189
Theodore Ts'o3839e651997-04-26 13:21:57 +0000190 if (retval) {
191 com_err("ncheck", retval,
192 "while doing inode scan");
193 goto error_out;
194 }
195 }
196
Theodore Ts'o3839e651997-04-26 13:21:57 +0000197error_out:
198 free(iw.iarray);
199 if (scan)
200 ext2fs_close_inode_scan(scan);
201 return;
202}
203
204
205