In the UAPI header files, __BIG_ENDIAN and __LITTLE_ENDIAN must be compared against __BYTE_ORDER in preprocessor conditionals where these are exposed to userspace (that is they're not inside __KERNEL__ conditionals). However, in the main kernel the norm is to check for "defined(__XXX_ENDIAN)" rather than comparing against __BYTE_ORDER and this has incorrectly leaked into the userspace headers. The definition of struct mdp_superblock_s in linux/raid/md_p.h is wrong in this way. Note that userspace will likely interpret the ordering of the fields incorrectly as the big-endian variant on a little-endian machines - depending on header inclusion order. [!!!] NOTE [!!!] This patch may adversely change the userspace API. It might be better to fix the ordering of events_hi, events_lo, cp_events_hi and cp_events_lo in struct mdp_superblock_s / typedef mdp_super_t.
Showing the changes to include/uapi/linux (1 of 1 file). Show all
Unified · Split
| @@ -145,16 +145,18 @@ typedef struct mdp_superblock_s { · 144 unmodified lines | |||
| 145 | __u32 failed_disks; /* 4 Number of failed disks */ | 145 | __u32 failed_disks; /* 4 Number of failed disks */ |
| 146 | __u32 spare_disks; /* 5 Number of spare disks */ | 146 | __u32 spare_disks; /* 5 Number of spare disks */ |
| 147 | __u32 sb_csum; /* 6 checksum of the whole superblock */ | 147 | __u32 sb_csum; /* 6 checksum of the whole superblock */ |
| 148 | #ifdef __BIG_ENDIAN | 148 | #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) |
| 149 | __u32 events_hi; /* 7 high-order of superblock update count */ | 149 | __u32 events_hi; /* 7 high-order of superblock update count */ |
| 150 | __u32 events_lo; /* 8 low-order of superblock update count */ | 150 | __u32 events_lo; /* 8 low-order of superblock update count */ |
| 151 | __u32 cp_events_hi; /* 9 high-order of checkpoint update count */ | 151 | __u32 cp_events_hi; /* 9 high-order of checkpoint update count */ |
| 152 | __u32 cp_events_lo; /* 10 low-order of checkpoint update count */ | 152 | __u32 cp_events_lo; /* 10 low-order of checkpoint update count */ |
| 153 | #else | 153 | #elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) |
| 154 | __u32 events_lo; /* 7 low-order of superblock update count */ | 154 | __u32 events_lo; /* 7 low-order of superblock update count */ |
| 155 | __u32 events_hi; /* 8 high-order of superblock update count */ | 155 | __u32 events_hi; /* 8 high-order of superblock update count */ |
| 156 | __u32 cp_events_lo; /* 9 low-order of checkpoint update count */ | 156 | __u32 cp_events_lo; /* 9 low-order of checkpoint update count */ |
| 157 | __u32 cp_events_hi; /* 10 high-order of checkpoint update count */ | 157 | __u32 cp_events_hi; /* 10 high-order of checkpoint update count */ |
| 158 | #else | ||
| 159 | #error unspecified endianness | ||
| 158 | #endif | 160 | #endif |
| 159 | __u32 recovery_cp; /* 11 recovery checkpoint sector count */ | 161 | __u32 recovery_cp; /* 11 recovery checkpoint sector count */ |
| 160 | /* There are only valid for minor_version > 90 */ | 162 | /* There are only valid for minor_version > 90 */ |