Enhance debugfs debug utility with dirdata display capabilities. This allows users to inspect Lustre File IDentifier (LUFID) and checksum hash (CFHASH) data embedded in directory entries. Signed-off-by: Andreas Dilger Signed-off-by: Pravin Shelar Signed-off-by: Artem Blagodarenko Reviewed-by: Andreas Dilger --- debugfs/debugfs.8.in | 7 ++++- debugfs/ls.c | 63 +++++++++++++++++++++++++++++++++++++++++--- debugfs/ncheck.c | 3 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index 08f41fdfa..5a5dd32b0 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -575,7 +575,7 @@ Instead, it will stop only when the entire log is printed or after .I num_trans transactions. .TP -.BI ls " [\-l] [\-c] [\-d] [\-p] [\-r] filespec" +.BI ls " [\-l] [\-c] [\-d] [\-p] [\-r] [\-D] filespec" Print a listing of the files in the directory .IR filespec . The @@ -595,6 +595,11 @@ non-printing characters at the end of filenames. The .I \-r flag will force the printing of the filename, even if it is encrypted. +The +.I \-D +flag will print the extra data found inside each entry when the +.I \-l +flag is used. .TP .BI list_deleted_inodes " [limit]" List deleted inodes, optionally limited to those deleted within diff --git a/debugfs/ls.c b/debugfs/ls.c index 613ad7380..d225982cb 100644 --- a/debugfs/ls.c +++ b/debugfs/ls.c @@ -24,6 +24,7 @@ extern char *optarg; #endif #include "debugfs.h" +#include "ext2fs/lfsck.h" /* * list directory @@ -32,6 +33,7 @@ extern char *optarg; #define LONG_OPT 0x0001 #define PARSE_OPT 0x0002 #define RAW_OPT 0x0004 +#define DIRDATA_OPT 0x0008 #define ENCRYPT_OPT 0x8000 struct list_dir_struct { @@ -44,6 +46,55 @@ struct list_dir_struct { static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +static void list_dirdata(struct list_dir_struct *ls, + struct ext2_dir_entry *dirent) +{ + unsigned char *data; + int dlen; + __u8 dirdata_mask; + __u8 file_type = dirent->name_len >> 8; + + data = (unsigned char *)dirent->name + + (dirent->name_len & EXT2_NAME_LEN) + 1; + + for (dirdata_mask = EXT2_FT_MASK + 1; + dirdata_mask != 0; dirdata_mask <<= 1) { + if ((dirdata_mask & file_type) == 0) + continue; + + dlen = data[0]; + + if (dirdata_mask == EXT2_DIRENT_LUFID) { + struct lu_fid fid; + int offset = 0; + fprintf(ls->f, " fid="); + while (offset < (dlen - 1)) { + memcpy(&fid, data + offset + 1, sizeof(fid)); + fid_be_to_cpu(&fid, &fid); + offset += sizeof(fid); + fprintf(ls->f, DFID, PFID(&fid)); + if (offset < (dlen - 1)) + fprintf(ls->f, ","); + } + } else if (dirdata_mask == EXT2_DIRENT_CFHASH) { + struct ext4_dirent_hash hash; + + memcpy(&hash, data, sizeof(hash)); + hash_le_to_cpu(&hash, &hash); + + fprintf(ls->f, "hash: 0x%08x, minor_hash: 0x%08x", + hash.dh_hash.hash, hash.dh_hash.minor_hash); + } else { + int i; + + for (i = 1; i < dlen; i++) + fprintf(ls->f, "%02x", data[i]); + } + + data += dlen; + } +} + static int print_filename(FILE *f, struct ext2_dir_entry *dirent, int options) { unsigned char ch; @@ -146,7 +197,10 @@ static int list_dir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)), inode_uid(inode), inode_gid(inode)); fprintf(ls->f, "%5llu", (unsigned long long) EXT2_I_SIZE(&inode)); - fprintf(ls->f, " %s ", datestr); + fprintf(ls->f, " %s", datestr); + if ((ls->options & DIRDATA_OPT) != 0) + list_dirdata(ls, dirent); + fprintf(ls->f, " "); print_filename(ls->f, dirent, options); fputc('\n', ls->f); } else { @@ -195,7 +249,7 @@ void do_list_dir(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)), return; reset_getopt(); - while ((c = getopt (argc, argv, "cdlpr")) != EOF) { + while ((c = getopt(argc, argv, "cdDlpr")) != EOF) { switch (c) { case 'c': flags |= DIRENT_FLAG_INCLUDE_CSUM; @@ -203,6 +257,9 @@ void do_list_dir(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)), case 'l': ls.options |= LONG_OPT; break; + case 'D': + ls.options |= DIRDATA_OPT; + break; case 'd': flags |= DIRENT_FLAG_INCLUDE_REMOVED; break; @@ -219,7 +276,7 @@ void do_list_dir(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)), if (argc > optind+1) { print_usage: - com_err(0, 0, "Usage: ls [-c] [-d] [-l] [-p] [-r] file"); + com_err(0, 0, "Usage: ls [-c] [-d] [-D] [-l] [-p] [-r] file"); return; } diff --git a/debugfs/ncheck.c b/debugfs/ncheck.c index 1410e7c6d..03d1e49cf 100644 --- a/debugfs/ncheck.c +++ b/debugfs/ncheck.c @@ -51,6 +51,9 @@ static int ncheck_proc(struct ext2_dir_entry *dirent, iw->position++; if (iw->position <= 2) return 0; + if (current_fs->super->s_feature_incompat & + EXT4_FEATURE_INCOMPAT_DIRDATA) + filetype &= EXT2_FT_MASK; for (i=0; i < iw->num_inodes; i++) { if (iw->iarray[i] == dirent->inode) { if (!iw->parent && !iw->get_pathname_failed) { -- 2.43.7