diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 632ca9aecef394a786a7ca9ca5f5b74d6d2ad35f..729c96fc0c870566e68078b46df98a9a4f7e19e1 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -315,6 +315,8 @@ struct p_header { u8 payload[0]; }; +extern unsigned int drbd_header_size(struct drbd_tconn *tconn); + /* * short commands, packets without payload, plain p_header: * P_PING diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 699ab11256beb9bb1605514bb4a3b7d5b86370a5..606a9ecbe044bf18cd63036d7109cf2b86de1cf6 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -689,6 +689,20 @@ void drbd_thread_current_set_cpu(struct drbd_thread *thi) } #endif +/** + * drbd_header_size - size of a packet header + * + * The header size is a multiple of 8, so any payload following the header is + * word aligned on 64-bit architectures. (The bitmap send and receive code + * relies on this.) + */ +unsigned int drbd_header_size(struct drbd_tconn *tconn) +{ + BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95)); + BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header80), 8)); + return sizeof(struct p_header80); +} + static void prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size) { h->magic = cpu_to_be32(DRBD_MAGIC); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 61104dbb01720a1a126c34f65d94094ae53ed7ad..e52a929d9ed3e3c181a5530f8138cf024f90261b 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -995,7 +995,7 @@ static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi) struct p_header *h = tconn->data.rbuf; int err; - err = drbd_recv_all_warn(tconn, h, sizeof(*h)); + err = drbd_recv_all_warn(tconn, h, drbd_header_size(tconn)); if (err) return err; @@ -4842,7 +4842,8 @@ int drbd_asender(struct drbd_thread *thi) int rv; void *buf = h; int received = 0; - int expect = sizeof(struct p_header); + unsigned int header_size = drbd_header_size(tconn); + int expect = header_size; int ping_timeout_active = 0; current->policy = SCHED_RR; /* Make this a realtime task! */ @@ -4926,7 +4927,7 @@ int drbd_asender(struct drbd_thread *thi) goto disconnect; } expect = cmd->pkt_size; - if (pi.size != expect - sizeof(struct p_header)) { + if (pi.size != expect - header_size) { conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n", pi.cmd, pi.size); goto reconnect; @@ -4950,7 +4951,7 @@ int drbd_asender(struct drbd_thread *thi) buf = h; received = 0; - expect = sizeof(struct p_header); + expect = header_size; cmd = NULL; } }