diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-03-08 16:15:14 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-03-08 16:15:14 -0500 |
commit | 30cbc591c34e680e8b5d6d675ea49effe42a0570 (patch) | |
tree | 8580f806e3ebe6f762bd4fb472d29539bd736034 | |
parent | 5110cd82ca90e6ce04c1c3264587c183aad1f179 (diff) |
xfs: check sizes of XFS on-disk structures at compile time
Check the sizes of XFS on-disk structures when compiling the kernel.
Use this to catch inadvertent changes in structure size due to padding
and alignment issues, etc.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/xfs_ondisk.h | 117 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 3 |
2 files changed, 120 insertions, 0 deletions
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h new file mode 100644 index 000000000000..184c44effdd5 --- /dev/null +++ b/fs/xfs/xfs_ondisk.h | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Oracle. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_ONDISK_H | ||
19 | #define __XFS_ONDISK_H | ||
20 | |||
21 | #define XFS_CHECK_STRUCT_SIZE(structname, size) \ | ||
22 | BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(" \ | ||
23 | #structname ") is wrong, expected " #size) | ||
24 | |||
25 | static inline void __init | ||
26 | xfs_check_ondisk_structs(void) | ||
27 | { | ||
28 | /* ag/file structures */ | ||
29 | XFS_CHECK_STRUCT_SIZE(struct xfs_acl, 4); | ||
30 | XFS_CHECK_STRUCT_SIZE(struct xfs_acl_entry, 12); | ||
31 | XFS_CHECK_STRUCT_SIZE(struct xfs_agf, 224); | ||
32 | XFS_CHECK_STRUCT_SIZE(struct xfs_agfl, 36); | ||
33 | XFS_CHECK_STRUCT_SIZE(struct xfs_agi, 336); | ||
34 | XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_key, 8); | ||
35 | XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_rec, 16); | ||
36 | XFS_CHECK_STRUCT_SIZE(struct xfs_bmdr_block, 4); | ||
37 | XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block, 72); | ||
38 | XFS_CHECK_STRUCT_SIZE(struct xfs_dinode, 176); | ||
39 | XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot, 104); | ||
40 | XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk, 136); | ||
41 | XFS_CHECK_STRUCT_SIZE(struct xfs_dsb, 264); | ||
42 | XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr, 56); | ||
43 | XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key, 4); | ||
44 | XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec, 16); | ||
45 | XFS_CHECK_STRUCT_SIZE(struct xfs_timestamp, 8); | ||
46 | XFS_CHECK_STRUCT_SIZE(xfs_alloc_key_t, 8); | ||
47 | XFS_CHECK_STRUCT_SIZE(xfs_alloc_ptr_t, 4); | ||
48 | XFS_CHECK_STRUCT_SIZE(xfs_alloc_rec_t, 8); | ||
49 | XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t, 4); | ||
50 | |||
51 | /* dir/attr trees */ | ||
52 | XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_leaf_hdr, 80); | ||
53 | XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_leafblock, 88); | ||
54 | XFS_CHECK_STRUCT_SIZE(struct xfs_attr3_rmt_hdr, 56); | ||
55 | XFS_CHECK_STRUCT_SIZE(struct xfs_da3_blkinfo, 56); | ||
56 | XFS_CHECK_STRUCT_SIZE(struct xfs_da3_intnode, 64); | ||
57 | XFS_CHECK_STRUCT_SIZE(struct xfs_da3_node_hdr, 64); | ||
58 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_blk_hdr, 48); | ||
59 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_data_hdr, 64); | ||
60 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free, 64); | ||
61 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free_hdr, 64); | ||
62 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf, 64); | ||
63 | XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf_hdr, 64); | ||
64 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_entry_t, 8); | ||
65 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_hdr_t, 32); | ||
66 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_map_t, 4); | ||
67 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_local_t, 4); | ||
68 | |||
69 | /* | ||
70 | * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to | ||
71 | * 4 bytes anyway so it's not obviously a problem. Hence for the moment | ||
72 | * we don't check this structure. This can be re-instated when the attr | ||
73 | * definitions are updated to use c99 VLA definitions. | ||
74 | * | ||
75 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_remote_t, 12); | ||
76 | */ | ||
77 | |||
78 | XFS_CHECK_STRUCT_SIZE(xfs_attr_leafblock_t, 40); | ||
79 | XFS_CHECK_STRUCT_SIZE(xfs_attr_shortform_t, 8); | ||
80 | XFS_CHECK_STRUCT_SIZE(xfs_da_blkinfo_t, 12); | ||
81 | XFS_CHECK_STRUCT_SIZE(xfs_da_intnode_t, 16); | ||
82 | XFS_CHECK_STRUCT_SIZE(xfs_da_node_entry_t, 8); | ||
83 | XFS_CHECK_STRUCT_SIZE(xfs_da_node_hdr_t, 16); | ||
84 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_free_t, 4); | ||
85 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_hdr_t, 16); | ||
86 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_unused_t, 6); | ||
87 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_hdr_t, 16); | ||
88 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_t, 16); | ||
89 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_ino4_t, 4); | ||
90 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_ino8_t, 8); | ||
91 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_inou_t, 8); | ||
92 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_entry_t, 8); | ||
93 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_hdr_t, 16); | ||
94 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_t, 16); | ||
95 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_tail_t, 4); | ||
96 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_entry_t, 3); | ||
97 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_hdr_t, 10); | ||
98 | XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_off_t, 2); | ||
99 | |||
100 | /* log structures */ | ||
101 | XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat, 24); | ||
102 | XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32, 28); | ||
103 | XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64, 32); | ||
104 | XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32, 28); | ||
105 | XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64, 32); | ||
106 | XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32, 12); | ||
107 | XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64, 16); | ||
108 | XFS_CHECK_STRUCT_SIZE(struct xfs_log_dinode, 176); | ||
109 | XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log, 28); | ||
110 | XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp, 8); | ||
111 | XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32, 52); | ||
112 | XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64, 56); | ||
113 | XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat, 20); | ||
114 | XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header, 16); | ||
115 | } | ||
116 | |||
117 | #endif /* __XFS_ONDISK_H */ | ||
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 59c9b7bd958d..3bd2027a7ea6 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "xfs_filestream.h" | 45 | #include "xfs_filestream.h" |
46 | #include "xfs_quota.h" | 46 | #include "xfs_quota.h" |
47 | #include "xfs_sysfs.h" | 47 | #include "xfs_sysfs.h" |
48 | #include "xfs_ondisk.h" | ||
48 | 49 | ||
49 | #include <linux/namei.h> | 50 | #include <linux/namei.h> |
50 | #include <linux/init.h> | 51 | #include <linux/init.h> |
@@ -1817,6 +1818,8 @@ init_xfs_fs(void) | |||
1817 | { | 1818 | { |
1818 | int error; | 1819 | int error; |
1819 | 1820 | ||
1821 | xfs_check_ondisk_structs(); | ||
1822 | |||
1820 | printk(KERN_INFO XFS_VERSION_STRING " with " | 1823 | printk(KERN_INFO XFS_VERSION_STRING " with " |
1821 | XFS_BUILD_OPTIONS " enabled\n"); | 1824 | XFS_BUILD_OPTIONS " enabled\n"); |
1822 | 1825 | ||