The __be* on-disk field types are annotated with __bitwise, which causes sparse to recognise them as conflicting with non-__bitwise types, but the endianness conversion macros don't have the required annotations to tell sparse when to resolve the conflicts instead of flagging a warning. Add __force annotations to the conversion macros.
This clears up a handful of sparse warnings but the anti-pattern of storing cpu-endian values in the on-disk structs is still common (see libgfs2/ondisk.c), so there are still some to be resolved. Signed-off-by: Andrew Price <anpr...@redhat.com> --- gfs2/convert/gfs2_convert.c | 2 +- gfs2/include/linux/types.h | 3 +++ gfs2/libgfs2/libgfs2.h | 49 ++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 5656b39d..ded2589e 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -1201,7 +1201,7 @@ static int process_dirent_info(struct gfs2_inode *dip, struct gfs2_sbd *sbp, /* Only do this if the dent was a true gfs1 dent, and not a */ /* gfs2 dent converted from a previously aborted run. */ if (dent_was_gfs1) { - switch be16_to_cpu(dent->de_type) { + switch (be16_to_cpu(dent->de_type)) { case GFS_FILE_NON: dent->de_type = cpu_to_be16(DT_UNKNOWN); break; diff --git a/gfs2/include/linux/types.h b/gfs2/include/linux/types.h index 7f4d4b98..a092afc0 100644 --- a/gfs2/include/linux/types.h +++ b/gfs2/include/linux/types.h @@ -7,10 +7,13 @@ #ifdef __CHECKER__ #define __bitwise__ __attribute__((bitwise)) +#define __force__ __attribute__((force)) #else #define __bitwise__ +#define __force__ #endif #define __bitwise __bitwise__ +#define __force __force__ typedef uint8_t __u8; typedef uint16_t __u16; diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index d8afc100..3f36ffb2 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -21,42 +21,41 @@ __BEGIN_DECLS #if __BYTE_ORDER == __BIG_ENDIAN -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#define be64_to_cpu(x) (x) +#define be16_to_cpu(x) ((__force uint16_t)(__be16)(x)) +#define be32_to_cpu(x) ((__force uint32_t)(__be32)(x)) +#define be64_to_cpu(x) ((__force uint64_t)(__be64)(x)) -#define cpu_to_be16(x) (x) -#define cpu_to_be32(x) (x) -#define cpu_to_be64(x) (x) +#define cpu_to_be16(x) ((__force __be16)(uint16_t)(x)) +#define cpu_to_be32(x) ((__force __be32)(uint32_t)(x)) +#define cpu_to_be64(x) ((__force __be64)(uint64_t)(x)) -#define le16_to_cpu(x) (bswap_16((x))) -#define le32_to_cpu(x) (bswap_32((x))) -#define le64_to_cpu(x) (bswap_64((x))) +#define le16_to_cpu(x) bswap_16((__force uint16_t)(__le16)(x)) +#define le32_to_cpu(x) bswap_32((__force uint32_t)(__le32)(x)) +#define le64_to_cpu(x) bswap_64((__force uint64_t)(__le64)(x)) -#define cpu_to_le16(x) (bswap_16((x))) -#define cpu_to_le32(x) (bswap_32((x))) -#define cpu_to_le64(x) (bswap_64((x))) +#define cpu_to_le16(x) ((__force __le16)bswap_16((x))) +#define cpu_to_le32(x) ((__force __le32)bswap_32((x))) +#define cpu_to_le64(x) ((__force __le64)bswap_64((x))) #endif /* __BYTE_ORDER == __BIG_ENDIAN */ - #if __BYTE_ORDER == __LITTLE_ENDIAN -#define be16_to_cpu(x) (bswap_16((x))) -#define be32_to_cpu(x) (bswap_32((x))) -#define be64_to_cpu(x) (bswap_64((x))) +#define be16_to_cpu(x) bswap_16((__force uint16_t)(__be16)(x)) +#define be32_to_cpu(x) bswap_32((__force uint32_t)(__be32)(x)) +#define be64_to_cpu(x) bswap_64((__force uint64_t)(__be64)(x)) -#define cpu_to_be16(x) (bswap_16((x))) -#define cpu_to_be32(x) (bswap_32((x))) -#define cpu_to_be64(x) (bswap_64((x))) +#define cpu_to_be16(x) ((__force __be16)bswap_16((x))) +#define cpu_to_be32(x) ((__force __be32)bswap_32((x))) +#define cpu_to_be64(x) ((__force __be64)bswap_64((x))) -#define le16_to_cpu(x) (x) -#define le32_to_cpu(x) (x) -#define le64_to_cpu(x) (x) +#define le16_to_cpu(x) ((__force uint16_t)(__le16)(x)) +#define le32_to_cpu(x) ((__force uint32_t)(__le32)(x)) +#define le64_to_cpu(x) ((__force uint64_t)(__le64)(x)) -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define cpu_to_le64(x) (x) +#define cpu_to_le16(x) ((__force __le16)(uint16_t)(x)) +#define cpu_to_le32(x) ((__force __le32)(uint32_t)(x)) +#define cpu_to_le64(x) ((__force __le64)(uint64_t)(x)) #endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ -- 2.30.2