#include #include #include #include "../src/erofs_fs.h" struct legacy_erofs_super_block { uint32_t magic; uint32_t checksum; uint32_t feature_compat; uint8_t blkszbits; uint8_t sb_extslots; union { uint16_t rootnid_2b; uint16_t blocks_hi; } __packed rb; uint64_t inos; uint64_t epoch; uint32_t fixed_nsec; uint32_t blocks_lo; uint32_t meta_blkaddr; uint32_t xattr_blkaddr; uint8_t uuid[16]; uint8_t volume_name[16]; uint32_t feature_incompat; union { uint16_t available_compr_algs; uint16_t lz4_max_distance; } __packed u1; uint16_t extra_devices; uint16_t devt_slotoff; uint8_t dirblkbits; uint8_t xattr_prefix_count; uint32_t xattr_prefix_start; uint64_t packed_nid; uint8_t xattr_filter_reserved; uint8_t ishare_xattr_prefix_id; uint8_t reserved[2]; uint32_t build_time; uint64_t rootnid_8b; uint64_t reserved2; uint64_t metabox_nid; uint64_t reserved3; } __packed; union legacy_erofs_inode_i_nb { uint16_t nlink; uint16_t blocks_hi; uint16_t startblk_hi; } __packed; struct legacy_erofs_inode_compact { uint16_t i_format; uint16_t i_xattr_icount; uint16_t i_mode; union legacy_erofs_inode_i_nb i_nb; uint32_t i_size; uint32_t i_mtime; union erofs_inode_i_u i_u; uint32_t i_ino; uint16_t i_uid; uint16_t i_gid; uint32_t i_reserved; } __packed; struct legacy_erofs_inode_extended { uint16_t i_format; uint16_t i_xattr_icount; uint16_t i_mode; union legacy_erofs_inode_i_nb i_nb; uint64_t i_size; union erofs_inode_i_u i_u; uint32_t i_ino; uint32_t i_uid; uint32_t i_gid; uint64_t i_mtime; uint32_t i_mtime_nsec; uint32_t i_nlink; uint8_t i_reserved2[16]; } __packed; struct legacy_erofs_dirent { uint64_t nid; uint16_t nameoff; uint8_t file_type; uint8_t reserved; } __packed; struct legacy_erofs_xattr_ibody_header { uint32_t h_name_filter; uint8_t h_shared_count; uint8_t h_reserved2[7]; uint32_t h_shared_xattrs[0]; } __packed; struct legacy_erofs_xattr_long_prefix { uint8_t base_index; char infix[0]; } __packed; struct legacy_erofs_xattr_entry { uint8_t e_name_len; uint8_t e_name_index; uint16_t e_value_size; char e_name[]; } __packed; #define ASSERT_LAYOUT(current, legacy) \ _Static_assert(sizeof(current) == sizeof(legacy), "size " #current); \ _Static_assert(_Alignof(current) == _Alignof(legacy), "align " #current) #define ASSERT_OFFSET(current, legacy, field) \ _Static_assert(offsetof(current, field) == offsetof(legacy, field), \ "offset " #current "." #field) ASSERT_LAYOUT(struct erofs_super_block, struct legacy_erofs_super_block); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, magic); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, checksum); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, feature_compat); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, blkszbits); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, sb_extslots); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, rb); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, inos); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, epoch); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, fixed_nsec); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, blocks_lo); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, meta_blkaddr); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, xattr_blkaddr); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, uuid); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, volume_name); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, feature_incompat); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, u1); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, extra_devices); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, devt_slotoff); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, dirblkbits); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, xattr_prefix_count); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, xattr_prefix_start); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, packed_nid); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, xattr_filter_reserved); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, ishare_xattr_prefix_id); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, reserved); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, build_time); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, rootnid_8b); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, reserved2); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, metabox_nid); ASSERT_OFFSET(struct erofs_super_block, struct legacy_erofs_super_block, reserved3); ASSERT_LAYOUT(union erofs_inode_i_nb, union legacy_erofs_inode_i_nb); ASSERT_OFFSET(union erofs_inode_i_nb, union legacy_erofs_inode_i_nb, nlink); ASSERT_OFFSET(union erofs_inode_i_nb, union legacy_erofs_inode_i_nb, blocks_hi); ASSERT_OFFSET(union erofs_inode_i_nb, union legacy_erofs_inode_i_nb, startblk_hi); #define ASSERT_INODE_LAYOUT(current, legacy) \ ASSERT_LAYOUT(current, legacy); \ ASSERT_OFFSET(current, legacy, i_format); \ ASSERT_OFFSET(current, legacy, i_xattr_icount); \ ASSERT_OFFSET(current, legacy, i_mode); \ ASSERT_OFFSET(current, legacy, i_nb); \ ASSERT_OFFSET(current, legacy, i_size); \ ASSERT_OFFSET(current, legacy, i_u); \ ASSERT_OFFSET(current, legacy, i_ino); \ ASSERT_OFFSET(current, legacy, i_uid); \ ASSERT_OFFSET(current, legacy, i_gid) ASSERT_INODE_LAYOUT(struct erofs_inode_compact, struct legacy_erofs_inode_compact); ASSERT_OFFSET(struct erofs_inode_compact, struct legacy_erofs_inode_compact, i_mtime); ASSERT_OFFSET(struct erofs_inode_compact, struct legacy_erofs_inode_compact, i_reserved); ASSERT_INODE_LAYOUT(struct erofs_inode_extended, struct legacy_erofs_inode_extended); ASSERT_OFFSET(struct erofs_inode_extended, struct legacy_erofs_inode_extended, i_mtime); ASSERT_OFFSET(struct erofs_inode_extended, struct legacy_erofs_inode_extended, i_mtime_nsec); ASSERT_OFFSET(struct erofs_inode_extended, struct legacy_erofs_inode_extended, i_nlink); ASSERT_OFFSET(struct erofs_inode_extended, struct legacy_erofs_inode_extended, i_reserved2); ASSERT_LAYOUT(struct erofs_dirent, struct legacy_erofs_dirent); ASSERT_OFFSET(struct erofs_dirent, struct legacy_erofs_dirent, nid); ASSERT_OFFSET(struct erofs_dirent, struct legacy_erofs_dirent, nameoff); ASSERT_OFFSET(struct erofs_dirent, struct legacy_erofs_dirent, file_type); ASSERT_OFFSET(struct erofs_dirent, struct legacy_erofs_dirent, reserved); ASSERT_LAYOUT(struct erofs_xattr_ibody_header, struct legacy_erofs_xattr_ibody_header); ASSERT_OFFSET(struct erofs_xattr_ibody_header, struct legacy_erofs_xattr_ibody_header, h_name_filter); ASSERT_OFFSET(struct erofs_xattr_ibody_header, struct legacy_erofs_xattr_ibody_header, h_shared_count); ASSERT_OFFSET(struct erofs_xattr_ibody_header, struct legacy_erofs_xattr_ibody_header, h_reserved2); ASSERT_OFFSET(struct erofs_xattr_ibody_header, struct legacy_erofs_xattr_ibody_header, h_shared_xattrs); ASSERT_LAYOUT(struct erofs_xattr_long_prefix, struct legacy_erofs_xattr_long_prefix); ASSERT_OFFSET(struct erofs_xattr_long_prefix, struct legacy_erofs_xattr_long_prefix, base_index); ASSERT_OFFSET(struct erofs_xattr_long_prefix, struct legacy_erofs_xattr_long_prefix, infix); ASSERT_LAYOUT(struct erofs_xattr_entry, struct legacy_erofs_xattr_entry); ASSERT_OFFSET(struct erofs_xattr_entry, struct legacy_erofs_xattr_entry, e_name_len); ASSERT_OFFSET(struct erofs_xattr_entry, struct legacy_erofs_xattr_entry, e_name_index); ASSERT_OFFSET(struct erofs_xattr_entry, struct legacy_erofs_xattr_entry, e_value_size); ASSERT_OFFSET(struct erofs_xattr_entry, struct legacy_erofs_xattr_entry, e_name); int main(void) { return (0); }