From: Sage Weil Date: Sat, 20 Jun 2009 21:55:20 +0000 (-0700) Subject: kclient: clean up unaligned pointer accesses X-Git-Tag: v0.10~186 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=aa615b84f5d1ba373f0a880ea90d3a8d3bbd794f;p=ceph.git kclient: clean up unaligned pointer accesses Get rid of the likes of *(__le64*)foo. Get rid of useless ceph_decode_##_le() macros; use ceph_decode_copy instead. --- diff --git a/src/kernel/decode.h b/src/kernel/decode.h index c34de0a0a53e..fc2769df062d 100644 --- a/src/kernel/decode.h +++ b/src/kernel/decode.h @@ -1,6 +1,8 @@ #ifndef __CEPH_DECODE_H #define __CEPH_DECODE_H +#include + /* * in all cases, * void **p pointer to position pointer @@ -16,20 +18,20 @@ goto bad; \ } while (0) -#define ceph_decode_64(p, v) \ - do { \ - v = le64_to_cpu(*(__le64 *)*(p)); \ - *(p) += sizeof(u64); \ +#define ceph_decode_64(p, v) \ + do { \ + v = get_unaligned_le64(*(p)); \ + *(p) += sizeof(u64); \ } while (0) -#define ceph_decode_32(p, v) \ - do { \ - v = le32_to_cpu(*(__le32 *)*(p)); \ - *(p) += sizeof(u32); \ +#define ceph_decode_32(p, v) \ + do { \ + v = get_unaligned_le32(*(p)); \ + *(p) += sizeof(u32); \ } while (0) -#define ceph_decode_16(p, v) \ - do { \ - v = le16_to_cpu(*(__le16 *)*(p)); \ - *(p) += sizeof(u16); \ +#define ceph_decode_16(p, v) \ + do { \ + v = get_unaligned_le16(*(p)); \ + *(p) += sizeof(u16); \ } while (0) #define ceph_decode_8(p, v) \ do { \ @@ -37,23 +39,6 @@ (*p)++; \ } while (0) -/* decode into an __le## */ -#define ceph_decode_64_le(p, v) \ - do { \ - v = *(__le64 *)*(p); \ - *(p) += sizeof(u64); \ - } while (0) -#define ceph_decode_32_le(p, v) \ - do { \ - v = *(__le32 *)*(p); \ - *(p) += sizeof(u32); \ - } while (0) -#define ceph_decode_16_le(p, v) \ - do { \ - v = *(__le16 *)*(p); \ - *(p) += sizeof(u16); \ - } while (0) - #define ceph_decode_copy(p, pv, n) \ do { \ memcpy(pv, *(p), n); \ @@ -101,20 +86,20 @@ /* * encoders */ -#define ceph_encode_64(p, v) \ - do { \ - *(__le64 *)*(p) = cpu_to_le64((v)); \ - *(p) += sizeof(u64); \ +#define ceph_encode_64(p, v) \ + do { \ + put_unaligned_le64(v, (__le64 *)*(p)); \ + *(p) += sizeof(u64); \ } while (0) -#define ceph_encode_32(p, v) \ - do { \ - *(__le32 *)*(p) = cpu_to_le32((v)); \ - *(p) += sizeof(u32); \ +#define ceph_encode_32(p, v) \ + do { \ + put_unaligned_le32(v, (__le32 *)*(p)); \ + *(p) += sizeof(u32); \ } while (0) -#define ceph_encode_16(p, v) \ - do { \ - *(__le16 *)*(p) = cpu_to_le16((v)); \ - *(p) += sizeof(u16); \ +#define ceph_encode_16(p, v) \ + do { \ + put_unaligned_le16(v), (__le16 *)*(p)); \ + *(p) += sizeof(u16); \ } while (0) #define ceph_encode_8(p, v) \ do { \ diff --git a/src/kernel/export.c b/src/kernel/export.c index 9e87065d96d7..50482f992e3c 100644 --- a/src/kernel/export.c +++ b/src/kernel/export.c @@ -1,4 +1,5 @@ #include +#include #include "super.h" #include "ceph_debug.h" @@ -29,7 +30,7 @@ struct ceph_export_item { struct ceph_vino ino; struct ceph_vino parent_ino; u32 parent_name_hash; -}; +} __attribute__ ((packed)); #define IPSZ ((sizeof(struct ceph_export_item) + sizeof(u32) + 1) / sizeof(u32)) @@ -137,10 +138,10 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { u32 *fh = fid->raw; - u64 ino = *(u64 *)fh; + u64 ino = get_unaligned((u64 *)fh); u32 hash = fh[2]; - derr(10, "fh_to_parent %llx.%x\n", ino, hash); + derr(10, "fh_to_parent %llx.%x\n", (unsigned long long)ino, hash); if (fh_len < 6) return ERR_PTR(-ESTALE); diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 6d0d3d68a542..0daa07df64e4 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -2174,7 +2174,7 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) mask = le16_to_cpu(h->mask); dname.name = (void *)h + sizeof(*h) + sizeof(u32); dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); - if (dname.len != le32_to_cpu(*(__le32 *)(h+1))) + if (dname.len != get_unaligned_le32(h+1)) goto bad; /* find session */ @@ -2285,9 +2285,8 @@ void ceph_mdsc_lease_send_msg(struct ceph_mds_client *mdsc, int mds, lease->ino = cpu_to_le64(ceph_vino(inode).ino); lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap); lease->seq = cpu_to_le32(seq); - *(__le32 *)((void *)lease + sizeof(*lease)) = cpu_to_le32(dnamelen); - memcpy((void *)lease + sizeof(*lease) + 4, dentry->d_name.name, - dnamelen); + put_unaligned_le32(dnamelen, lease + 1); + memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen); /* * if this is a preemptive lease RELEASE, no need to @@ -2623,7 +2622,6 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) ceph_fsid_t fsid; int err = -EINVAL; int from; - __le64 major, minor; if (le32_to_cpu(msg->hdr.src.name.type) == CEPH_ENTITY_TYPE_MDS) from = le32_to_cpu(msg->hdr.src.name.num); @@ -2631,10 +2629,7 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) from = -1; ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); - ceph_decode_64_le(&p, major); - __ceph_fsid_set_major(&fsid, major); - ceph_decode_64_le(&p, minor); - __ceph_fsid_set_minor(&fsid, minor); + ceph_decode_copy(&p, &fsid, sizeof(fsid)); if (ceph_fsid_compare(&fsid, &mdsc->client->monc.monmap->fsid)) { derr(0, "got mdsmap with wrong fsid\n"); return; diff --git a/src/kernel/mon_client.c b/src/kernel/mon_client.c index 555178719366..5b4e5e9711e0 100644 --- a/src/kernel/mon_client.c +++ b/src/kernel/mon_client.c @@ -19,7 +19,7 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) { struct ceph_monmap *m; int i, err = -EINVAL; - __le64 major, minor; + ceph_fsid_t fsid; dout(30, "monmap_decode %p %p len %d\n", p, end, (int)(end-p)); @@ -29,10 +29,7 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) return ERR_PTR(-ENOMEM); ceph_decode_need(&p, end, 2*sizeof(u32) + 2*sizeof(u64), bad); - ceph_decode_64_le(&p, major); - __ceph_fsid_set_major(&m->fsid, major); - ceph_decode_64_le(&p, minor); - __ceph_fsid_set_minor(&m->fsid, minor); + ceph_decode_copy(&p, &m->fsid, sizeof(fsid)); ceph_decode_32(&p, m->epoch); ceph_decode_32(&p, m->num_mon); ceph_decode_need(&p, end, m->num_mon*sizeof(m->mon_inst[0]), bad); diff --git a/src/kernel/osd_client.c b/src/kernel/osd_client.c index ddad5c12a6de..ccb770de923f 100644 --- a/src/kernel/osd_client.c +++ b/src/kernel/osd_client.c @@ -180,7 +180,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, head->snap_seq = cpu_to_le64(snapc->seq); head->num_snaps = cpu_to_le32(snapc->num_snaps); for (i = 0; i < snapc->num_snaps; i++) { - *(__le64 *)p = cpu_to_le64(snapc->snaps[i]); + put_unaligned_le64(snapc->snaps[i], p); p += sizeof(u64); } } @@ -590,7 +590,6 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) struct ceph_osdmap *newmap = NULL, *oldmap; int err; ceph_fsid_t fsid; - __le64 major, minor; dout(2, "handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0); p = msg->front.iov_base; @@ -598,10 +597,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) /* verify fsid */ ceph_decode_need(&p, end, sizeof(fsid), bad); - ceph_decode_64_le(&p, major); - __ceph_fsid_set_major(&fsid, major); - ceph_decode_64_le(&p, minor); - __ceph_fsid_set_minor(&fsid, minor); + ceph_decode_copy(&p, &fsid, sizeof(fsid)); if (ceph_fsid_compare(&fsid, &osdc->client->monc.monmap->fsid)) { derr(0, "got map with wrong fsid, ignoring\n"); return; diff --git a/src/kernel/osdmap.c b/src/kernel/osdmap.c index 1e4f832971f3..555c2025ff18 100644 --- a/src/kernel/osdmap.c +++ b/src/kernel/osdmap.c @@ -372,7 +372,6 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) u32 len, max, i; int err = -EINVAL; void *start = *p; - __le64 major, minor; dout(30, "osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p)); @@ -381,15 +380,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) return ERR_PTR(-ENOMEM); ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad); - ceph_decode_64_le(p, major); - __ceph_fsid_set_major(&map->fsid, major); - ceph_decode_64_le(p, minor); - __ceph_fsid_set_minor(&map->fsid, minor); + ceph_decode_copy(p, &map->fsid, sizeof(map->fsid)); ceph_decode_32(p, map->epoch); - ceph_decode_32_le(p, map->created.tv_sec); - ceph_decode_32_le(p, map->created.tv_nsec); - ceph_decode_32_le(p, map->modified.tv_sec); - ceph_decode_32_le(p, map->modified.tv_nsec); + ceph_decode_copy(p, &map->created, sizeof(map->created)); + ceph_decode_copy(p, &map->modified, sizeof(map->modified)); ceph_decode_32(p, map->num_pools); map->pg_pool = kmalloc(map->num_pools * sizeof(*map->pg_pool), @@ -478,18 +472,13 @@ struct ceph_osdmap *apply_incremental(void **p, void *end, __s32 new_flags, max; void *start = *p; int err = -EINVAL; - __le64 major, minor; ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32), bad); - ceph_decode_64_le(p, major); - __ceph_fsid_set_major(&fsid, major); - ceph_decode_64_le(p, minor); - __ceph_fsid_set_minor(&fsid, minor); + ceph_decode_copy(p, &fsid, sizeof(fsid)); ceph_decode_32(p, epoch); BUG_ON(epoch != map->epoch+1); - ceph_decode_32_le(p, modified.tv_sec); - ceph_decode_32_le(p, modified.tv_nsec); + ceph_decode_copy(p, &modified, sizeof(modified)); ceph_decode_32(p, new_flags); /* full map? */ diff --git a/src/kernel/super.h b/src/kernel/super.h index 1eaf82e79792..db184d4efcfb 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -1,6 +1,7 @@ #ifndef _FS_CEPH_SUPER_H #define _FS_CEPH_SUPER_H +#include #include #include #include @@ -763,22 +764,22 @@ extern const char *ceph_msg_type_name(int type); static inline __le64 __ceph_fsid_minor(ceph_fsid_t *fsid) { - return *(__le64 *)&fsid->fsid[8]; + return get_unaligned_le64(&fsid->fsid[8]); } static inline __le64 __ceph_fsid_major(ceph_fsid_t *fsid) { - return *(__le64 *)&fsid->fsid[0]; + return get_unaligned_le64(&fsid->fsid[0]); } static inline void __ceph_fsid_set_minor(ceph_fsid_t *fsid, __le64 val) { - *(__le64 *)&fsid->fsid[8] = val; + put_unaligned_le64(val, &fsid->fsid[8]); } static inline void __ceph_fsid_set_major(ceph_fsid_t *fsid, __le64 val) { - *(__le64 *)&fsid->fsid[0] = val; + put_unaligned_le64(val, &fsid->fsid[0]); } /* inode.c */