From: Theodore Ts'o Date: Sun, 27 May 2018 03:11:18 +0000 (-0400) Subject: debugfs: add -b and -e options to the inode_dump command X-Git-Tag: v1.44.3-rc1~68 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fe2fsprogs.git;a=commitdiff_plain;h=dd1543dba446c21e856b32926e1afc229566bc51 debugfs: add -b and -e options to the inode_dump command Teach the inode_dump command to dump out just the i_block array and the extra space in the inode, as a convenience to someone investigating a corrupted inode. Signed-off-by: Theodore Ts'o --- diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index 4b5f472e9..358f802bf 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -424,8 +424,16 @@ showing its tree structure. Print a listing of the inodes which use the one or more blocks specified on the command line. .TP -.BI inode_dump " filespec" +.BI inode_dump " [-b]|[-e] filespec" Print the contents of the inode data structure in hex and ASCII format. +The +.I \-b +option causes the command to only dump the contents of the +.B i_blocks +array. The +.I \-e +option causes the command to only dump the contents of the extra inode +space, which is used to store in-line extended attributes. .TP .BI imap " filespec" Print the location of the inode data structure (in the inode table) diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c index 905c8cdc6..3780d3949 100644 --- a/debugfs/debugfs.c +++ b/debugfs/debugfs.c @@ -2097,15 +2097,30 @@ void do_imap(int argc, char *argv[]) void do_idump(int argc, char *argv[]) { + struct ext2_inode_large *inode; ext2_ino_t ino; unsigned char *buf; errcode_t err; - int isize; + unsigned int isize, size, offset = 0; + int c, mode = 0; - if (common_args_process(argc, argv, 2, 2, argv[0], - "", 0)) + reset_getopt(); + while ((c = getopt (argc, argv, "be")) != EOF) { + if (mode || c == '?') { + print_usage: + com_err(argv[0], 0, + "Usage: inode_dump [-b]|[-e] "); + return; + } + mode = c; + } + if (optind != argc-1) return; - ino = string_to_inode(argv[1]); + + if (check_fs_open(argv[0])) + return; + + ino = string_to_inode(argv[optind]); if (!ino) return; @@ -2123,7 +2138,26 @@ void do_idump(int argc, char *argv[]) goto err; } - do_byte_hexdump(stdout, buf, isize); + inode = (struct ext2_inode_large *) buf; + size = isize; + switch (mode) { + case 'b': + offset = ((char *) (&inode->i_block)) - ((char *) buf); + size = sizeof(inode->i_block); + break; + case 'e': + if (size <= EXT2_GOOD_OLD_INODE_SIZE) { + no_extra_space: + com_err(argv[0], 0, "No extra space in inode"); + goto err; + } + offset = EXT2_GOOD_OLD_INODE_SIZE + inode->i_extra_isize; + if (offset > size) + goto err; + size -= offset; + break; + } + do_byte_hexdump(stdout, buf + offset, size); err: ext2fs_free_mem(&buf); } diff --git a/debugfs/zap.c b/debugfs/zap.c index 0a1ae9b9d..047e7856b 100644 --- a/debugfs/zap.c +++ b/debugfs/zap.c @@ -234,29 +234,33 @@ errout: void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize) { - size_t i, j; + size_t i, j, max; int suppress = -1; for (i = 0; i < bufsize; i += 16) { + max = (bufsize - i > 16) ? 16 : bufsize - i; if (suppress < 0) { - if (i && memcmp(buf + i, buf + i - 16, 16) == 0) { + if (i && memcmp(buf + i, buf + i - max, max) == 0) { suppress = i; fprintf(fp, "*\n"); continue; } } else { - if (memcmp(buf + i, buf + suppress, 16) == 0) + if (memcmp(buf + i, buf + suppress, max) == 0) continue; suppress = -1; } fprintf(fp, "%04o ", (unsigned int)i); for (j = 0; j < 16; j++) { - fprintf(fp, "%02x", buf[i+j]); + if (j < max) + fprintf(fp, "%02x", buf[i+j]); + else + fprintf(fp, " "); if ((j % 2) == 1) fprintf(fp, " "); } fprintf(fp, " "); - for (j = 0; j < 16; j++) + for (j = 0; j < max; j++) fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.'); fprintf(fp, "\n"); }