1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2016 Oracle. 4 * All Rights Reserved. 5 */ 6 #ifndef __XFS_ONDISK_H 7 #define __XFS_ONDISK_H 8 9 #define XFS_CHECK_STRUCT_SIZE(structname, size) \ 10 static_assert(sizeof(structname) == (size), \ 11 "XFS: sizeof(" #structname ") is wrong, expected " #size) 12 13 #define XFS_CHECK_OFFSET(structname, member, off) \ 14 static_assert(offsetof(structname, member) == (off), \ 15 "XFS: offsetof(" #structname ", " #member ") is wrong, " \ 16 "expected " #off) 17 18 #define XFS_CHECK_VALUE(value, expected) \ 19 static_assert((value) == (expected), \ 20 "XFS: value of " #value " is wrong, expected " #expected) 21 22 #define XFS_CHECK_SB_OFFSET(field, offset) \ 23 XFS_CHECK_OFFSET(struct xfs_dsb, field, offset); \ 24 XFS_CHECK_OFFSET(struct xfs_sb, field, offset); 25 26 static inline void __init 27 xfs_check_ondisk_structs(void) 28 { 29 /* file structures */ 30 XFS_CHECK_STRUCT_SIZE(struct xfs_acl, 4); 31 XFS_CHECK_STRUCT_SIZE(struct xfs_acl_entry, 12); 32 XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_key, 8); 33 XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_rec, 16); 34 XFS_CHECK_STRUCT_SIZE(struct xfs_bmdr_block, 4); 35 XFS_CHECK_STRUCT_SIZE(struct xfs_dinode, 176); 36 XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot, 104); 37 XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk, 136); 38 XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr, 56); 39 XFS_CHECK_STRUCT_SIZE(xfs_timestamp_t, 8); 40 XFS_CHECK_STRUCT_SIZE(struct xfs_legacy_timestamp, 8); 41 42 /* space btrees */ 43 XFS_CHECK_STRUCT_SIZE(struct xfs_agf, 224); 44 XFS_CHECK_STRUCT_SIZE(struct xfs_agfl, 36); 45 XFS_CHECK_STRUCT_SIZE(struct xfs_agi, 344); 46 XFS_CHECK_STRUCT_SIZE(struct xfs_alloc_rec, 8); 47 XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block, 72); 48 XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block_lhdr, 64); 49 XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block_shdr, 48); 50 XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key, 4); 51 XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec, 16); 52 XFS_CHECK_STRUCT_SIZE(struct xfs_refcount_key, 4); 53 XFS_CHECK_STRUCT_SIZE(struct xfs_refcount_rec, 12); 54 XFS_CHECK_STRUCT_SIZE(struct xfs_rmap_key, 20); 55 XFS_CHECK_STRUCT_SIZE(struct xfs_rmap_rec, 24); 56 XFS_CHECK_STRUCT_SIZE(xfs_alloc_key_t, 8); 57 XFS_CHECK_STRUCT_SIZE(xfs_alloc_ptr_t, 4); 58 XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t, 4); 59 XFS_CHECK_STRUCT_SIZE(xfs_refcount_ptr_t, 4); 60 XFS_CHECK_STRUCT_SIZE(xfs_rmap_ptr_t, 4); 61 XFS_CHECK_STRUCT_SIZE(xfs_bmdr_key_t, 8); 62 63 /* dir/attr trees */ 64 XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_leaf_hdr, 80); 65 XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_leafblock, 80); 66 XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_rmt_hdr, 56); 67 XFS_CHECK_STRUCT_SIZE(struct xfs_da3_blkinfo, 56); 68 XFS_CHECK_STRUCT_SIZE(struct xfs_da3_intnode, 64); 69 XFS_CHECK_STRUCT_SIZE(struct xfs_da3_node_hdr, 64); 70 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_blk_hdr, 48); 71 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_data_hdr, 64); 72 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free, 64); 73 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free_hdr, 64); 74 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf, 64); 75 XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf_hdr, 64); 76 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_entry, 8); 77 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_hdr, 32); 78 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_map, 4); 79 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_name_local, 4); 80 81 /* realtime structures */ 82 XFS_CHECK_STRUCT_SIZE(struct xfs_rtsb, 56); 83 XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw, 4); 84 XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_raw, 4); 85 XFS_CHECK_STRUCT_SIZE(struct xfs_rtbuf_blkinfo, 48); 86 87 /* 88 * m68k has problems with struct xfs_attr_leaf_name_remote, but we pad 89 * it to 4 bytes anyway so it's not obviously a problem. Hence for the 90 * moment we don't check this structure. This can be re-instated when 91 * the attr definitions are updated to use c99 VLA definitions. 92 * 93 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_name_remote, 12); 94 */ 95 96 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_local, valuelen, 0); 97 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_local, namelen, 2); 98 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_local, nameval, 3); 99 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_remote, valueblk, 0); 100 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_remote, valuelen, 4); 101 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_remote, namelen, 8); 102 XFS_CHECK_OFFSET(struct xfs_attr_leaf_name_remote, name, 9); 103 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leafblock, 32); 104 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_sf_hdr, 4); 105 XFS_CHECK_OFFSET(struct xfs_attr_sf_hdr, totsize, 0); 106 XFS_CHECK_OFFSET(struct xfs_attr_sf_hdr, count, 2); 107 XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, namelen, 0); 108 XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, valuelen, 1); 109 XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, flags, 2); 110 XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, nameval, 3); 111 XFS_CHECK_STRUCT_SIZE(struct xfs_da_blkinfo, 12); 112 XFS_CHECK_STRUCT_SIZE(struct xfs_da_intnode, 16); 113 XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_entry, 8); 114 XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_hdr, 16); 115 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free, 4); 116 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr, 16); 117 XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, freetag, 0); 118 XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, length, 2); 119 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free_hdr, 16); 120 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free, 16); 121 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_entry, 8); 122 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_hdr, 16); 123 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf, 16); 124 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_tail, 4); 125 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_entry, 3); 126 XFS_CHECK_OFFSET(struct xfs_dir2_sf_entry, namelen, 0); 127 XFS_CHECK_OFFSET(struct xfs_dir2_sf_entry, offset, 1); 128 XFS_CHECK_OFFSET(struct xfs_dir2_sf_entry, name, 3); 129 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_hdr, 10); 130 XFS_CHECK_STRUCT_SIZE(struct xfs_parent_rec, 12); 131 132 /* ondisk dir/attr structures from xfs/122 */ 133 XFS_CHECK_STRUCT_SIZE(struct xfs_attr_sf_entry, 3); 134 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free, 4); 135 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr, 16); 136 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_unused, 6); 137 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free, 16); 138 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free_hdr, 16); 139 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf, 16); 140 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_entry, 8); 141 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_hdr, 16); 142 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_tail, 4); 143 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_entry, 3); 144 XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_hdr, 10); 145 146 /* log structures */ 147 XFS_CHECK_STRUCT_SIZE(struct xfs_buf_log_format, 88); 148 XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat, 24); 149 XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32, 16); 150 XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64, 16); 151 XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32, 16); 152 XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64, 16); 153 XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32, 12); 154 XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64, 16); 155 XFS_CHECK_STRUCT_SIZE(struct xfs_log_dinode, 176); 156 XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log, 28); 157 XFS_CHECK_STRUCT_SIZE(xfs_log_timestamp_t, 8); 158 XFS_CHECK_STRUCT_SIZE(struct xfs_log_legacy_timestamp, 8); 159 XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32, 52); 160 XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format, 56); 161 XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat, 20); 162 XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header, 16); 163 XFS_CHECK_STRUCT_SIZE(struct xfs_attri_log_format, 40); 164 XFS_CHECK_STRUCT_SIZE(struct xfs_attrd_log_format, 16); 165 XFS_CHECK_STRUCT_SIZE(struct xfs_bui_log_format, 16); 166 XFS_CHECK_STRUCT_SIZE(struct xfs_bud_log_format, 16); 167 XFS_CHECK_STRUCT_SIZE(struct xfs_cui_log_format, 16); 168 XFS_CHECK_STRUCT_SIZE(struct xfs_cud_log_format, 16); 169 XFS_CHECK_STRUCT_SIZE(struct xfs_rui_log_format, 16); 170 XFS_CHECK_STRUCT_SIZE(struct xfs_rud_log_format, 16); 171 XFS_CHECK_STRUCT_SIZE(struct xfs_map_extent, 32); 172 XFS_CHECK_STRUCT_SIZE(struct xfs_phys_extent, 16); 173 174 XFS_CHECK_OFFSET(struct xfs_bui_log_format, bui_extents, 16); 175 XFS_CHECK_OFFSET(struct xfs_cui_log_format, cui_extents, 16); 176 XFS_CHECK_OFFSET(struct xfs_rui_log_format, rui_extents, 16); 177 XFS_CHECK_OFFSET(struct xfs_efi_log_format, efi_extents, 16); 178 XFS_CHECK_OFFSET(struct xfs_efi_log_format_32, efi_extents, 16); 179 XFS_CHECK_OFFSET(struct xfs_efi_log_format_64, efi_extents, 16); 180 181 /* ondisk log structures from xfs/122 */ 182 XFS_CHECK_STRUCT_SIZE(struct xfs_unmount_log_format, 8); 183 XFS_CHECK_STRUCT_SIZE(struct xfs_xmd_log_format, 16); 184 XFS_CHECK_STRUCT_SIZE(struct xfs_xmi_log_format, 88); 185 186 /* parent pointer ioctls */ 187 XFS_CHECK_STRUCT_SIZE(struct xfs_getparents_rec, 32); 188 XFS_CHECK_STRUCT_SIZE(struct xfs_getparents, 40); 189 XFS_CHECK_STRUCT_SIZE(struct xfs_getparents_by_handle, 64); 190 191 /* 192 * The v5 superblock format extended several v4 header structures with 193 * additional data. While new fields are only accessible on v5 194 * superblocks, it's important that the v5 structures place original v4 195 * fields/headers in the correct location on-disk. For example, we must 196 * be able to find magic values at the same location in certain blocks 197 * regardless of superblock version. 198 * 199 * The following checks ensure that various v5 data structures place the 200 * subset of v4 metadata associated with the same type of block at the 201 * start of the on-disk block. If there is no data structure definition 202 * for certain types of v4 blocks, traverse down to the first field of 203 * common metadata (e.g., magic value) and make sure it is at offset 204 * zero. 205 */ 206 XFS_CHECK_OFFSET(struct xfs_dir3_leaf, hdr.info.hdr, 0); 207 XFS_CHECK_OFFSET(struct xfs_da3_intnode, hdr.info.hdr, 0); 208 XFS_CHECK_OFFSET(struct xfs_dir3_data_hdr, hdr.magic, 0); 209 XFS_CHECK_OFFSET(struct xfs_dir3_free, hdr.hdr.magic, 0); 210 XFS_CHECK_OFFSET(struct xfs_attr3_leafblock, hdr.info.hdr, 0); 211 212 XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat, 192); 213 XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers, 24); 214 XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req, 64); 215 XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req, 64); 216 217 /* 218 * Make sure the incore inode timestamp range corresponds to hand 219 * converted values based on the ondisk format specification. 220 */ 221 XFS_CHECK_VALUE(XFS_BIGTIME_TIME_MIN - XFS_BIGTIME_EPOCH_OFFSET, 222 XFS_LEGACY_TIME_MIN); 223 XFS_CHECK_VALUE(XFS_BIGTIME_TIME_MAX - XFS_BIGTIME_EPOCH_OFFSET, 224 16299260424LL); 225 226 /* Do the same with the incore quota expiration range. */ 227 XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MIN << XFS_DQ_BIGTIME_SHIFT, 4); 228 XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MAX << XFS_DQ_BIGTIME_SHIFT, 229 16299260424LL); 230 231 /* superblock field checks we got from xfs/122 */ 232 XFS_CHECK_STRUCT_SIZE(struct xfs_dsb, 288); 233 XFS_CHECK_STRUCT_SIZE(struct xfs_sb, 288); 234 XFS_CHECK_SB_OFFSET(sb_magicnum, 0); 235 XFS_CHECK_SB_OFFSET(sb_blocksize, 4); 236 XFS_CHECK_SB_OFFSET(sb_dblocks, 8); 237 XFS_CHECK_SB_OFFSET(sb_rblocks, 16); 238 XFS_CHECK_SB_OFFSET(sb_rextents, 24); 239 XFS_CHECK_SB_OFFSET(sb_uuid, 32); 240 XFS_CHECK_SB_OFFSET(sb_logstart, 48); 241 XFS_CHECK_SB_OFFSET(sb_rootino, 56); 242 XFS_CHECK_SB_OFFSET(sb_rbmino, 64); 243 XFS_CHECK_SB_OFFSET(sb_rsumino, 72); 244 XFS_CHECK_SB_OFFSET(sb_rextsize, 80); 245 XFS_CHECK_SB_OFFSET(sb_agblocks, 84); 246 XFS_CHECK_SB_OFFSET(sb_agcount, 88); 247 XFS_CHECK_SB_OFFSET(sb_rbmblocks, 92); 248 XFS_CHECK_SB_OFFSET(sb_logblocks, 96); 249 XFS_CHECK_SB_OFFSET(sb_versionnum, 100); 250 XFS_CHECK_SB_OFFSET(sb_sectsize, 102); 251 XFS_CHECK_SB_OFFSET(sb_inodesize, 104); 252 XFS_CHECK_SB_OFFSET(sb_inopblock, 106); 253 XFS_CHECK_SB_OFFSET(sb_blocklog, 120); 254 XFS_CHECK_SB_OFFSET(sb_fname[12], 120); 255 XFS_CHECK_SB_OFFSET(sb_sectlog, 121); 256 XFS_CHECK_SB_OFFSET(sb_inodelog, 122); 257 XFS_CHECK_SB_OFFSET(sb_inopblog, 123); 258 XFS_CHECK_SB_OFFSET(sb_agblklog, 124); 259 XFS_CHECK_SB_OFFSET(sb_rextslog, 125); 260 XFS_CHECK_SB_OFFSET(sb_inprogress, 126); 261 XFS_CHECK_SB_OFFSET(sb_imax_pct, 127); 262 XFS_CHECK_SB_OFFSET(sb_icount, 128); 263 XFS_CHECK_SB_OFFSET(sb_ifree, 136); 264 XFS_CHECK_SB_OFFSET(sb_fdblocks, 144); 265 XFS_CHECK_SB_OFFSET(sb_frextents, 152); 266 XFS_CHECK_SB_OFFSET(sb_uquotino, 160); 267 XFS_CHECK_SB_OFFSET(sb_gquotino, 168); 268 XFS_CHECK_SB_OFFSET(sb_qflags, 176); 269 XFS_CHECK_SB_OFFSET(sb_flags, 178); 270 XFS_CHECK_SB_OFFSET(sb_shared_vn, 179); 271 XFS_CHECK_SB_OFFSET(sb_inoalignmt, 180); 272 XFS_CHECK_SB_OFFSET(sb_unit, 184); 273 XFS_CHECK_SB_OFFSET(sb_width, 188); 274 XFS_CHECK_SB_OFFSET(sb_dirblklog, 192); 275 XFS_CHECK_SB_OFFSET(sb_logsectlog, 193); 276 XFS_CHECK_SB_OFFSET(sb_logsectsize, 194); 277 XFS_CHECK_SB_OFFSET(sb_logsunit, 196); 278 XFS_CHECK_SB_OFFSET(sb_features2, 200); 279 XFS_CHECK_SB_OFFSET(sb_bad_features2, 204); 280 XFS_CHECK_SB_OFFSET(sb_features_compat, 208); 281 XFS_CHECK_SB_OFFSET(sb_features_ro_compat, 212); 282 XFS_CHECK_SB_OFFSET(sb_features_incompat, 216); 283 XFS_CHECK_SB_OFFSET(sb_features_log_incompat, 220); 284 XFS_CHECK_SB_OFFSET(sb_crc, 224); 285 XFS_CHECK_SB_OFFSET(sb_spino_align, 228); 286 XFS_CHECK_SB_OFFSET(sb_pquotino, 232); 287 XFS_CHECK_SB_OFFSET(sb_lsn, 240); 288 XFS_CHECK_SB_OFFSET(sb_meta_uuid, 248); 289 XFS_CHECK_SB_OFFSET(sb_metadirino, 264); 290 XFS_CHECK_SB_OFFSET(sb_rgcount, 272); 291 XFS_CHECK_SB_OFFSET(sb_rgextents, 276); 292 XFS_CHECK_SB_OFFSET(sb_rgblklog, 280); 293 XFS_CHECK_SB_OFFSET(sb_pad, 281); 294 } 295 296 #endif /* __XFS_ONDISK_H */ 297