summaryrefslogtreecommitdiff
path: root/debugfs
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-05-26 23:11:18 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-05-26 23:11:18 -0400
commitdd1543dba446c21e856b32926e1afc229566bc51 (patch)
treeba662f453e04b15c4a065224b64e9e5b7178083e /debugfs
parent0310a3d7558f2a28e6c93eea9fe4ae5c73a3fd0e (diff)
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 <tytso@mit.edu>
Diffstat (limited to 'debugfs')
-rw-r--r--debugfs/debugfs.8.in10
-rw-r--r--debugfs/debugfs.c44
-rw-r--r--debugfs/zap.c14
3 files changed, 57 insertions, 11 deletions
diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in
index 4b5f472e..358f802b 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 905c8cdc..3780d394 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],
- "<file>", 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] <file>");
+ 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 0a1ae9b9..047e7856 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");
}