Whamcloud - gitweb
LU-4017 e2fsprogs: always read full inode structure
[tools/e2fsprogs.git] / debugfs / ncheck.c
index 09b844c..10a38a3 100644 (file)
 #include <errno.h>
 #endif
 #include <sys/types.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern int optind;
+extern char *optarg;
+#endif
 
 #include "debugfs.h"
 
@@ -26,7 +32,8 @@ struct inode_walk_struct {
        int                     num_inodes;
        int                     position;
        char                    *parent;
-       unsigned int            get_pathname_failed;
+       unsigned int            get_pathname_failed:1;
+       unsigned int            check_dirent:1;
 };
 
 static int ncheck_proc(struct ext2_dir_entry *dirent,
@@ -36,7 +43,9 @@ static int ncheck_proc(struct ext2_dir_entry *dirent,
                       void     *private)
 {
        struct inode_walk_struct *iw = (struct inode_walk_struct *) private;
+       struct ext2_inode inode;
        errcode_t       retval;
+       int             filetype = dirent->name_len >> 8;
        int             i;
 
        iw->position++;
@@ -55,13 +64,21 @@ static int ncheck_proc(struct ext2_dir_entry *dirent,
                                }
                        }
                        if (iw->parent)
-                               printf("%u\t%s/%.*s\n", iw->iarray[i],
+                               printf("%u\t%s/%.*s", iw->iarray[i],
                                       iw->parent,
                                       (dirent->name_len & 0xFF), dirent->name);
                        else
-                               printf("%u\t<%u>/%.*s\n", iw->iarray[i],
+                               printf("%u\t<%u>/%.*s", iw->iarray[i],
                                       iw->dir,
                                       (dirent->name_len & 0xFF), dirent->name);
+                       if (iw->check_dirent && filetype) {
+                               if (!debugfs_read_inode(dirent->inode, &inode,
+                                                       "ncheck") &&
+                                   filetype != ext2_file_type(inode.i_mode)) {
+                                       printf("  <--- BAD FILETYPE");
+                               }
+                       }
+                       putc('\n', stdout);
                }
        }
        if (!iw->inodes_left)
@@ -73,15 +90,32 @@ static int ncheck_proc(struct ext2_dir_entry *dirent,
 void do_ncheck(int argc, char **argv)
 {
        struct inode_walk_struct iw;
-       int                     i;
+       int                     c, i;
        ext2_inode_scan         scan = 0;
        ext2_ino_t              ino;
-       struct ext2_inode       inode;
+       struct ext2_inode       *inode = NULL;
+       int                     inode_size;
        errcode_t               retval;
        char                    *tmp;
 
-       if (argc < 2) {
-               com_err(argv[0], 0, "Usage: ncheck <inode number> ...");
+       iw.check_dirent = 0;
+
+       reset_getopt();
+       while ((c = getopt (argc, argv, "c")) != EOF) {
+               switch (c) {
+               case 'c':
+                       iw.check_dirent = 1;
+                       break;
+               default:
+                       goto print_usage;
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (argc < 1) {
+       print_usage:
+               com_err(argv[0], 0, "Usage: ncheck [-c] <inode number> ...");
                return;
        }
        if (check_fs_open(argv[0]))
@@ -90,29 +124,34 @@ void do_ncheck(int argc, char **argv)
        iw.iarray = malloc(sizeof(ext2_ino_t) * argc);
        if (!iw.iarray) {
                com_err("ncheck", ENOMEM,
-                       "while allocating inode info array");
+                       "while allocating inode number array");
                return;
        }
        memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc);
 
-       for (i=1; i < argc; i++) {
-               iw.iarray[i-1] = strtol(argv[i], &tmp, 0);
+       for (i=0; i < argc; i++) {
+               iw.iarray[i] = strtol(argv[i], &tmp, 0);
                if (*tmp) {
                        com_err(argv[0], 0, "Bad inode - %s", argv[i]);
                        goto error_out;
                }
        }
 
-       iw.num_inodes = iw.inodes_left = argc-1;
+       iw.num_inodes = iw.inodes_left = argc;
 
        retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
        if (retval) {
                com_err("ncheck", retval, "while opening inode scan");
                goto error_out;
        }
+       inode_size = EXT2_INODE_SIZE(current_fs->super);
+       retval = ext2fs_get_mem(inode_size, &inode);
+       if (retval)
+               goto error_out;
 
        do {
-               retval = ext2fs_get_next_inode(scan, &ino, &inode);
+               retval = ext2fs_get_next_inode_full(scan, &ino,
+                                               inode, inode_size);
        } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
        if (retval) {
                com_err("ncheck", retval, "while starting inode scan");
@@ -121,16 +160,16 @@ void do_ncheck(int argc, char **argv)
 
        printf("Inode\tPathname\n");
        while (ino) {
-               if (!inode.i_links_count)
+               if (!inode->i_links_count)
                        goto next;
                /*
                 * To handle filesystems touched by 0.3c extfs; can be
                 * removed later.
                 */
-               if (inode.i_dtime)
+               if (inode->i_dtime)
                        goto next;
                /* Ignore anything that isn't a directory */
-               if (!LINUX_S_ISDIR(inode.i_mode))
+               if (!LINUX_S_ISDIR(inode->i_mode))
                        goto next;
 
                iw.position = 0;
@@ -152,7 +191,8 @@ void do_ncheck(int argc, char **argv)
 
        next:
                do {
-                       retval = ext2fs_get_next_inode(scan, &ino, &inode);
+                       retval = ext2fs_get_next_inode_full(scan, &ino,
+                                                       inode, inode_size);
                } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
 
                if (retval) {
@@ -163,6 +203,7 @@ void do_ncheck(int argc, char **argv)
        }
 
 error_out:
+       ext2fs_free_mem(inode);
        free(iw.iarray);
        if (scan)
                ext2fs_close_inode_scan(scan);