From 8bf1e9184ed607aca8afaf50f0972c5a5a9a32db Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 17 Jan 2012 17:08:39 -0500 Subject: [PATCH] debugfs: add ncheck -c option Add a -c option to ncheck will verifies the file type information in the directory entry. Signed-off-by: "Theodore Ts'o" --- debugfs/debugfs.8.in | 7 +++++-- debugfs/debugfs.c | 29 ---------------------------- debugfs/debugfs.h | 1 + debugfs/ncheck.c | 53 ++++++++++++++++++++++++++++++++++++++++++---------- debugfs/util.c | 29 ++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 41 deletions(-) diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index 70c8326..08d9068 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -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 diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c index b7ff00d..04d5139 100644 --- a/debugfs/debugfs.c +++ b/debugfs/debugfs.c @@ -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; diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h index eb044b1..994577c 100644 --- a/debugfs/debugfs.h +++ b/debugfs/debugfs.h @@ -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 */ diff --git a/debugfs/ncheck.c b/debugfs/ncheck.c index 09b844c..1e169cf 100644 --- a/debugfs/ncheck.c +++ b/debugfs/ncheck.c @@ -16,6 +16,12 @@ #include #endif #include +#ifdef HAVE_GETOPT_H +#include +#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 ..."); + 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] ..."); 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) { diff --git a/debugfs/util.c b/debugfs/util.c index 1a23730..7cbf34d 100644 --- a/debugfs/util.c +++ b/debugfs/util.c @@ -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; +} -- 1.8.3.1