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. Define dirdata feature add some other helper functions. Signed-off-by: Andreas Dilger Signed-off-by: Pravin Shelar Signed-off-by: Artem Blagodarenko Reviewed-by: Andreas Dilger --- lib/ext2fs/ext2_fs.h | 30 +++++++++++++++++++++++++++- lib/ext2fs/ext2fs.h | 3 ++- lib/ext2fs/lfsck.h | 47 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index a4141eb71..73e93f9b9 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -977,7 +977,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(casefold, 4, CASEFOLD) #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ EXT4_FEATURE_INCOMPAT_MMP| \ EXT4_FEATURE_INCOMPAT_LARGEDIR| \ - EXT4_FEATURE_INCOMPAT_EA_INODE) + EXT4_FEATURE_INCOMPAT_EA_INODE| \ + EXT4_FEATURE_INCOMPAT_DIRDATA) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ @@ -1135,6 +1136,33 @@ static inline unsigned int ext2fs_dir_rec_len(__u8 name_len, return rec_len; } +static inline unsigned int ext2fs_dirdata_rec_len(struct ext2_dir_entry *de, + int extended) +{ + int rec_len = EXT2_DIRENT_REC_LEN(de); + + if (extended) + rec_len += EXT2_DIR_ENTRY_HASH_LEN; + return rec_len; +} + +static inline unsigned int ext2fs_dir_rec_padding(struct ext2_dir_entry *de) +{ + unsigned int len = (de->name_len & EXT2_NAME_LEN) + + ext2_get_dirdata_size(de); + + len &= EXT2_DIR_ROUND; + if (len) + len = EXT2_DIR_PAD - len; + return len; +} + +/* lu_fid size and NUL char */ +#define EXT2_DIRENT_LUFID_SIZE 16 +#define EXT2_DIRENT_LUFID 0x10 +#define EXT2_DIRENT_INO64 0x20 +#define EXT2_DIRENT_CFHASH 0x40 + #define EXT4_ORPHAN_BLOCK_MAGIC 0x0b10ca04 /* Structure at the tail of orphan block */ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 374b8289e..91d269865 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -735,6 +735,7 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_EA_INODE|\ + EXT4_FEATURE_INCOMPAT_DIRDATA|\ EXT4_LIB_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT|\ EXT4_FEATURE_INCOMPAT_INLINE_DATA|\ @@ -2340,7 +2341,7 @@ _INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b) _INLINE_ int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry) { - return entry->name_len & 0xff; + return entry->name_len & EXT2_NAME_LEN; } _INLINE_ void ext2fs_dirent_set_name_len(struct ext2_dir_entry *entry, int len) diff --git a/lib/ext2fs/lfsck.h b/lib/ext2fs/lfsck.h new file mode 100644 index 000000000..ec763f720 --- /dev/null +++ b/lib/ext2fs/lfsck.h @@ -0,0 +1,47 @@ +#ifndef LFSCK_H +#define LFSCK_H + +struct ext4_dirent_data_header { + /* length of this header + the whole data blob */ + __u8 ddh_length; +} __attribute__((packed)); + +#ifndef DFID +#define DFID "[%#llx:0x%x:0x%x]" +#define PFID(fid) (unsigned long long)(fid)->f_seq, (fid)->f_oid, (fid)->f_ver +struct lu_fid { + __u64 f_seq; + __u32 f_oid; + __u32 f_ver; +}; +#endif /* !DFID */ + +static inline void fid_be_to_cpu(struct lu_fid *dst, struct lu_fid *src) +{ + dst->f_seq = ext2fs_be64_to_cpu(src->f_seq); + dst->f_oid = ext2fs_be32_to_cpu(src->f_oid); + dst->f_ver = ext2fs_be32_to_cpu(src->f_ver); +} + +struct ext4_dirent_lufid { + struct ext4_dirent_data_header df_header; + struct lu_fid df_fid[]; +}; + +struct ext4_dir_entry_hash { + __le32 hash; + __le32 minor_hash; +}; + +struct ext4_dirent_hash { + struct ext4_dirent_data_header dh_header; + struct ext4_dir_entry_hash dh_hash; +} __attribute__((packed)); + +static inline void hash_le_to_cpu(struct ext4_dirent_hash *dst, + struct ext4_dirent_hash *src) +{ + dst->dh_hash.hash = ext2fs_le32_to_cpu(src->dh_hash.hash); + dst->dh_hash.minor_hash = ext2fs_le32_to_cpu(src->dh_hash.minor_hash); +} +#endif /* LFSCK_H */ -- 2.43.7