From: Lukas Czerner <lczerner@xxxxxxxxxx> Wrong directory block number can be saved in ->previous on big endian system in parse_int_node(). Fix it by moving the mask out of the endian conversion. Fixes: ae9efd05a986 ("e2fsck: 3 level hash tree directory optimization") Signed-off-by: Lukas Czerner <lczerner@xxxxxxxxxx> Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> --- e2fsck/pass2.c | 5 +++-- lib/ext2fs/ext2_fs.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 1b0504c85..e922876d3 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -643,7 +643,7 @@ static void parse_int_node(ext2_filsys fs, printf("Entry #%d: Hash 0x%08x, block %u\n", i, hash, ext2fs_le32_to_cpu(ent[i].block)); #endif - blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff; + blk = ext2fs_le32_to_cpu(ent[i].block) & EXT4_DX_BLOCK_MASK; /* Check to make sure the block is valid */ if (blk >= (blk_t) dx_dir->numblocks) { cd->pctx.blk = blk; @@ -664,7 +664,8 @@ static void parse_int_node(ext2_filsys fs, } dx_db->previous = - i ? ext2fs_le32_to_cpu(ent[i-1].block & 0x0ffffff) : 0; + i ? (ext2fs_le32_to_cpu(ent[i-1].block) & + EXT4_DX_BLOCK_MASK) : 0; if (hash < min_hash) min_hash = hash; diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 2496d16da..7d6269413 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -232,6 +232,8 @@ struct ext2_dx_root_info { #define EXT2_HASH_FLAG_INCOMPAT 0x1 +#define EXT4_DX_BLOCK_MASK 0x0fffffff + struct ext2_dx_entry { __le32 hash; __le32 block; -- 2.16.1.72.g5be1f00a9a