From: Ulrich Weigand Date: Mon, 2 Sep 2019 19:21:17 +0000 (+0200) Subject: include: Endian fix for shared kernel/user headers X-Git-Tag: v14.2.5~173^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dbf0947e2d703faa26954cbd4688514da62db795;p=ceph.git include: Endian fix for shared kernel/user headers Endian swapping is done differently in kernel space vs. user space, but a few header files are shared between those two user cases. Current code attempts to handle this by re-defining __le16/32/64 before pulling those headers into user space, but this is not consistenly done: when ceph_fs.h is included via types.h, the redefinition happens, but when ceph_fs.h is directly included, the redefinition does not happen. Fix this by performing the same redefinition directly *in* those shared headers, when included by user space. Note that the redefines where also in effect for rbd_types.h, which is *not* shared with the kernel, so in the file I'm simply replacing __le16/32/64 with ceph_le16/32/64 in-line. Also note that it is now no longer possible to include any of the three files using the redefined macros in C code (as they make use of C++ features). However, this currently happens in exactly one file, src/mds/locks.c, which only uses a few CEPH_CAP_... constants from the header. To fix this, I've simply duplicated those definitions, which are unchangeable ABI constants anyway. Fixes (partially): https://tracker.ceph.com/issues/41605 Signed-off-by: Ulrich Weigand (cherry picked from commit 743ed43a785795412cdda16e3d25b12cb9228a32) Signed-off-by: Ulrich Weigand --- diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index fd12b9f12541..1c73ff377bc0 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -15,6 +15,27 @@ #include "msgr.h" #include "rados.h" +/* + * The data structures defined here are shared between Linux kernel and + * user space. Also, those data structures are maintained always in + * little-endian byte order, even on big-endian systems. This is handled + * differently in kernel vs. user space. For use as kernel headers, the + * little-endian fields need to use the __le16/__le32/__le64 types. These + * are markers that indicate endian conversion routines must be used + * whenever such fields are accessed, which can be verified by checker + * tools like "sparse". For use as user-space headers, the little-endian + * fields instead use types ceph_le16/ceph_le32/ceph_le64, which are C++ + * classes that implement automatic endian conversion on every access. + * To still allow for header sharing, this file uses the __le types, but + * redefines those to the ceph_ types when compiled in user space. + */ +#ifndef __KERNEL__ +#include "byteorder.h" +#define __le16 ceph_le16 +#define __le32 ceph_le32 +#define __le64 ceph_le64 +#endif + /* * subprotocol versions. when specific messages types or high-level * protocols change, bump the affected components. we keep rev @@ -710,6 +731,7 @@ int ceph_flags_to_mode(int flags); #define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */ /* generic cap bits */ +/* note: these definitions are duplicated in mds/locks.c */ #define CEPH_CAP_GSHARED 1 /* client can reads */ #define CEPH_CAP_GEXCL 2 /* client can read and update */ #define CEPH_CAP_GCACHE 4 /* (file) client can cache reads */ @@ -951,4 +973,10 @@ struct ceph_mds_snap_realm { } __attribute__ ((packed)); /* followed by my snap list, then prior parent snap list */ +#ifndef __KERNEL__ +#undef __le16 +#undef __le32 +#undef __le64 +#endif + #endif diff --git a/src/include/msgr.h b/src/include/msgr.h index 4029443d0a4e..bda810808247 100644 --- a/src/include/msgr.h +++ b/src/include/msgr.h @@ -7,6 +7,14 @@ #include "include/int_types.h" +/* See comment in ceph_fs.h. */ +#ifndef __KERNEL__ +#include "byteorder.h" +#define __le16 ceph_le16 +#define __le32 ceph_le32 +#define __le64 ceph_le64 +#endif + /* * Data types for message passing layer used by Ceph. */ @@ -236,5 +244,10 @@ struct ceph_msg_footer { #define CEPH_MSG_FOOTER_NOCRC (1<<1) /* no data crc */ #define CEPH_MSG_FOOTER_SIGNED (1<<2) /* msg was signed */ +#ifndef __KERNEL__ +#undef __le16 +#undef __le32 +#undef __le64 +#endif #endif diff --git a/src/include/rados.h b/src/include/rados.h index 53320d65410c..6cf951f2d8fa 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -9,6 +9,14 @@ #include #include "msgr.h" +/* See comment in ceph_fs.h. */ +#ifndef __KERNEL__ +#include "byteorder.h" +#define __le16 ceph_le16 +#define __le32 ceph_le32 +#define __le64 ceph_le64 +#endif + /* * fs id */ @@ -663,5 +671,10 @@ struct ceph_osd_reply_head { struct ceph_osd_op ops[0]; /* ops[], object */ } __attribute__ ((packed)); +#ifndef __KERNEL__ +#undef __le16 +#undef __le32 +#undef __le64 +#endif #endif diff --git a/src/include/rbd_types.h b/src/include/rbd_types.h index 94799ab6f1de..4401a36c8ba9 100644 --- a/src/include/rbd_types.h +++ b/src/include/rbd_types.h @@ -119,12 +119,12 @@ #define RBD_MIRROR_PEER_CONFIG_KEY_PREFIX "rbd/mirror/peer/" struct rbd_info { - __le64 max_id; + ceph_le64 max_id; } __attribute__ ((packed)); struct rbd_obj_snap_ondisk { - __le64 id; - __le64 image_size; + ceph_le64 id; + ceph_le64 image_size; } __attribute__((packed)); struct rbd_obj_header_ondisk { @@ -138,11 +138,11 @@ struct rbd_obj_header_ondisk { __u8 comp_type; __u8 unused; } __attribute__((packed)) options; - __le64 image_size; - __le64 snap_seq; - __le32 snap_count; - __le32 reserved; - __le64 snap_names_len; + ceph_le64 image_size; + ceph_le64 snap_seq; + ceph_le32 snap_count; + ceph_le32 reserved; + ceph_le64 snap_names_len; struct rbd_obj_snap_ondisk snaps[0]; } __attribute__((packed)); diff --git a/src/include/types.h b/src/include/types.h index 04c62e389740..1ae1527758de 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -24,19 +24,9 @@ #include #include -// -// temporarily remap __le* to ceph_le* for benefit of shared kernel/userland headers -#define __le16 ceph_le16 -#define __le32 ceph_le32 -#define __le64 ceph_le64 #include "ceph_fs.h" #include "ceph_frag.h" #include "rbd_types.h" -#undef __le16 -#undef __le32 -#undef __le64 -// - #ifdef __cplusplus #ifndef _BACKWARD_BACKWARD_WARNING_H diff --git a/src/mds/locks.c b/src/mds/locks.c index c788407fb0af..fad782ba6a09 100644 --- a/src/mds/locks.c +++ b/src/mds/locks.c @@ -8,9 +8,18 @@ typedef char bool; #include #include -#include "include/ceph_fs.h" #include "locks.h" +/* Duplicated from ceph_fs.h, which we cannot include into a C file. */ +#define CEPH_CAP_GSHARED 1 /* client can reads */ +#define CEPH_CAP_GEXCL 2 /* client can read and update */ +#define CEPH_CAP_GCACHE 4 /* (file) client can cache reads */ +#define CEPH_CAP_GRD 8 /* (file) client can read */ +#define CEPH_CAP_GWR 16 /* (file) client can write */ +#define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes */ +#define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF */ +#define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io */ + static const struct sm_state_t simplelock[LOCK_MAX] = { // stable loner rep state r rp rd wr fwr l x caps,other [LOCK_SYNC] = { 0, false, LOCK_SYNC, ANY, 0, ANY, 0, 0, ANY, 0, CEPH_CAP_GSHARED,0,0,CEPH_CAP_GSHARED },