Add FID extraction and error message formatting for dirdata, plus pass3 support for proper error reporting with Lustre-specific metadata. Signed-off-by: Andreas Dilger Signed-off-by: Pravin Shelar Signed-off-by: Artem Blagodarenko Reviewed-by: Andreas Dilger --- e2fsck/message.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++- e2fsck/pass3.c | 7 ++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/e2fsck/message.c b/e2fsck/message.c index 9c42b13fb..193d887ec 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -99,6 +99,7 @@ #include "e2fsck.h" #include "problem.h" +#include "ext2fs/lfsck.h" #ifdef __GNUC__ #define _INLINE_ __inline__ @@ -346,6 +347,41 @@ static _INLINE_ void expand_inode_expression(FILE *f, ext2_filsys fs, char ch, } } +int get_dirent_fid(struct ext2_dir_entry *dirent, struct lu_fid **fids) +{ + unsigned char *data = (unsigned char *)dirent->name + + (dirent->name_len & EXT2_NAME_LEN) + 1; + __u8 file_type = dirent->name_len >> 8; + __u8 dirdata_mask; + int retlen = 0; + + for (dirdata_mask = EXT2_FT_MASK + 1; + dirdata_mask != 0; dirdata_mask <<= 1) { + int dlen; + + if ((dirdata_mask & file_type) == 0) + continue; + + dlen = data[0]; + if (dirdata_mask == EXT2_DIRENT_LUFID) { + struct lu_fid *fid; + int len = dlen; + + *fids = (struct lu_fid *)(data + 1); + for (fid = *fids; len >= sizeof(*fid); fid++, + len -= sizeof(*fid)) { + memcpy(fid, data + 1, sizeof(*fid)); + fid_be_to_cpu(fid, fid); + } + retlen = dlen; + break; + } + data += dlen; + } + + return retlen; +} + /* * This function expands '%dX' expressions */ @@ -361,9 +397,26 @@ static _INLINE_ void expand_dirent_expression(FILE *f, ext2_filsys fs, char ch, dirent = ctx->dirent; switch (ch) { - case 'i': + case 'i': { + struct lu_fid *fids; + int i; + int fids_len; + fprintf(f, "%u", dirent->inode); + + fids_len = get_dirent_fid(dirent, &fids); + if (fids_len > sizeof(*fids)) + fprintf(f, " fid="); + while (fids_len > sizeof(*fids)) { + fprintf(f, DFID, PFID(fids)); + fids++; + fids_len -= sizeof(*fids); + if (fids_len >= sizeof(*fids)) + fprintf(f, ","); + } + break; + } case 'n': len = ext2fs_dirent_name_len(dirent); if ((ext2fs_get_rec_len(fs, dirent, &rec_len) == 0) && diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 56798b1bc..343609832 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -706,6 +706,7 @@ static int fix_dotdot_proc(struct ext2_dir_entry *dirent, struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data; errcode_t retval; struct problem_context pctx; + __u16 dirdata = 0; if (ext2fs_dirent_name_len(dirent) != 2) return 0; @@ -725,11 +726,17 @@ static int fix_dotdot_proc(struct ext2_dir_entry *dirent, fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); } dirent->inode = fp->parent; + + dirdata = dirent->name_len & ((__u16)~EXT2_FT_MASK << 8); + if (ext2fs_has_feature_filetype(fp->ctx->fs->super)) ext2fs_dirent_set_file_type(dirent, EXT2_FT_DIR); else ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN); + if (ext2fs_has_feature_dirdata(fp->ctx->fs->super)) + dirent->name_len |= dirdata; + fp->done++; return DIRENT_ABORT | DIRENT_CHANGED; } -- 2.43.7