Whamcloud - gitweb
debugfs: add ncheck -c option
authorTheodore Ts'o <tytso@mit.edu>
Tue, 17 Jan 2012 22:08:39 +0000 (17:08 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 17 Jan 2012 22:08:39 +0000 (17:08 -0500)
Add a -c option to ncheck will verifies the file type information in
the directory entry.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
debugfs/debugfs.8.in
debugfs/debugfs.c
debugfs/debugfs.h
debugfs/ncheck.c
debugfs/util.c

index 70c8326..08d9068 100644 (file)
@@ -427,9 +427,12 @@ and
 .I minor
 device numbers must be specified.
 .TP
-.I ncheck inode_num ...
+.I ncheck [-c] inode_num ...
 Take the requested list of inode numbers, and print a listing of pathnames
-to those inodes.
+to those inodes.  The
+.I -c
+flag will enable checking the file type information in the directory
+entry to make sure it matches the inode's type.
 .TP
 .I open [-w] [-e] [-f] [-i] [-c] [-D] [-b blocksize] [-s superblock] device
 Open a filesystem for editing.  The 
index b7ff00d..04d5139 100644 (file)
@@ -1287,35 +1287,6 @@ void do_print_working_directory(int argc, char *argv[])
 }
 
 #ifndef READ_ONLY
-/*
- * Given a mode, return the ext2 file type
- */
-static int ext2_file_type(unsigned int mode)
-{
-       if (LINUX_S_ISREG(mode))
-               return EXT2_FT_REG_FILE;
-
-       if (LINUX_S_ISDIR(mode))
-               return EXT2_FT_DIR;
-
-       if (LINUX_S_ISCHR(mode))
-               return EXT2_FT_CHRDEV;
-
-       if (LINUX_S_ISBLK(mode))
-               return EXT2_FT_BLKDEV;
-
-       if (LINUX_S_ISLNK(mode))
-               return EXT2_FT_SYMLINK;
-
-       if (LINUX_S_ISFIFO(mode))
-               return EXT2_FT_FIFO;
-
-       if (LINUX_S_ISSOCK(mode))
-               return EXT2_FT_SOCK;
-
-       return 0;
-}
-
 static void make_link(char *sourcename, char *destname)
 {
        ext2_ino_t      ino;
index eb044b1..994577c 100644 (file)
@@ -54,6 +54,7 @@ extern int debugfs_write_inode_full(ext2_ino_t ino, struct ext2_inode * inode,
                                    const char *cmd, int bufsize);
 extern int debugfs_write_new_inode(ext2_ino_t ino, struct ext2_inode * inode,
                                   const char *cmd);
+extern int ext2_file_type(unsigned int mode);
 
 /* ss command functions */
 
index 09b844c..1e169cf 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 FILETYLE");
+                               }
+                       }
+                       putc('\n', stdout);
                }
        }
        if (!iw->inodes_left)
@@ -73,15 +90,31 @@ 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;
        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,20 +123,20 @@ 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) {
index 1a23730..7cbf34d 100644 (file)
@@ -443,3 +443,32 @@ int debugfs_write_new_inode(ext2_ino_t ino, struct ext2_inode * inode,
        }
        return 0;
 }
+
+/*
+ * Given a mode, return the ext2 file type
+ */
+int ext2_file_type(unsigned int mode)
+{
+       if (LINUX_S_ISREG(mode))
+               return EXT2_FT_REG_FILE;
+
+       if (LINUX_S_ISDIR(mode))
+               return EXT2_FT_DIR;
+
+       if (LINUX_S_ISCHR(mode))
+               return EXT2_FT_CHRDEV;
+
+       if (LINUX_S_ISBLK(mode))
+               return EXT2_FT_BLKDEV;
+
+       if (LINUX_S_ISLNK(mode))
+               return EXT2_FT_SYMLINK;
+
+       if (LINUX_S_ISFIFO(mode))
+               return EXT2_FT_FIFO;
+
+       if (LINUX_S_ISSOCK(mode))
+               return EXT2_FT_SOCK;
+
+       return 0;
+}