Add dirdata support infrastructure in the new lfsck.h header, with data structures (lu_fid, ext4_dirent_data_header, ext4_dirent_hash) related to dirdata fields. Also changes to ext2_fs.h and ext2fs.h to support INCOMPAT_DIRDATA. Signed-off-by: Artem Blagodarenko Reviewed-by: Andreas Dilger --- debugfs/htree.c | 2 +- e2fsck/pass1.c | 2 +- e2fsck/pass2.c | 7 +++---- lib/ext2fs/ext2fs.h | 19 +++++++++++++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/debugfs/htree.c b/debugfs/htree.c index 4ea8f30b3..efb858271 100644 --- a/debugfs/htree.c +++ b/debugfs/htree.c @@ -298,7 +298,7 @@ void do_htree_dump(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)), goto errout; } - rootnode = (struct ext2_dx_root_info *) (buf + 24); + rootnode = ext2fs_get_dx_root_info(current_fs, buf); fprintf(pager, "Root node dump:\n"); fprintf(pager, "\t Reserved zero: %u\n", rootnode->reserved_zero); diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 39d1255f9..12925ce2f 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -2801,7 +2801,7 @@ static int handle_htree(e2fsck_t ctx, struct problem_context *pctx, return 1; /* XXX should check that beginning matches a directory */ - root = (struct ext2_dx_root_info *) (block_buf + 24); + root = ext2fs_get_dx_root_info(fs, block_buf); if ((root->reserved_zero || root->info_length < 8) && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 319e7e0e3..cf1678c85 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -650,7 +650,7 @@ static void parse_int_node(ext2_filsys fs, int csum_size = 0; if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (block_buf + 24); + root = ext2fs_get_dx_root_info(fs, block_buf); #ifdef DX_DEBUG printf("Root node dump:\n"); @@ -677,8 +677,7 @@ static void parse_int_node(ext2_filsys fs, &cd->pctx))) goto clear_and_exit; } - - limit = (struct ext2_dx_countlimit *) ent; + limit = (struct ext2_dx_countlimit *)ent; #ifdef DX_DEBUG printf("Number of entries (count): %d\n", @@ -1236,7 +1235,7 @@ inline_read_fail: (void) ext2fs_get_rec_len(fs, dirent, &rec_len); limit = (struct ext2_dx_countlimit *) (buf+8); if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (buf + 24); + root = ext2fs_get_dx_root_info(fs, buf); dx_db->type = DX_DIRBLOCK_ROOT; dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 91d269865..cf12716e3 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -2262,6 +2262,25 @@ _INLINE_ int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks) sizeof(struct ext2_dx_entry)); } +_INLINE_ struct ext2_dx_root_info *ext2fs_get_dx_root_info(ext2_filsys fs, + char *buf) +{ + struct ext2_dir_entry *de = (struct ext2_dir_entry *)buf; + + if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA)) + return (struct ext2_dx_root_info *)(buf + + EXT2_DIR_NAME_LEN(1) + + EXT2_DIR_NAME_LEN(2)); + + /* get dotdot first */ + de = (struct ext2_dir_entry *)((char *)de + de->rec_len); + + /* dx root info is after dotdot entry */ + de = EXT2_NEXT_DIRENT(de); + + return (struct ext2_dx_root_info *)de; +} + /* * log base 2, rounded down */ -- 2.43.7