aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-03-30 10:00:17 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:45:10 -0500
commit0c8e36d9b843be56e4e43d4ef3c3eb6a97205599 (patch)
tree5f593c0b3c4a4052382fa2d23dff87281786e2ad /drivers
parente658983af6e62304be785cd6b0ae756723057395 (diff)
drbd: Introduce protocol version 100 headers
The 8 byte header finally becomes too small. With the protocol 100 header we have 16 bit for the volume number, proper 32 bit for the data length, and 32 bit for further extensions in the future. Previous versions of drbd are using version 80 headers for all packets short enough for protocol 80. They support both header versions in worker context, but only version 80 headers in asynchronous context. For backwards compatibility, continue to use version 80 headers for short packets before protocol version 100. From protocol version 100 on, use the same header version for all packets. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_int.h8
-rw-r--r--drivers/block/drbd/drbd_main.c32
-rw-r--r--drivers/block/drbd/drbd_nl.c3
-rw-r--r--drivers/block/drbd/drbd_receiver.c14
4 files changed, 47 insertions, 10 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 6d55bb75a081..bf1aad683387 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -307,6 +307,14 @@ struct p_header95 {
307 u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */ 307 u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */
308} __packed; 308} __packed;
309 309
310struct p_header100 {
311 u32 magic;
312 u16 volume;
313 u16 command;
314 u32 length;
315 u32 pad;
316} __packed;
317
310extern unsigned int drbd_header_size(struct drbd_tconn *tconn); 318extern unsigned int drbd_header_size(struct drbd_tconn *tconn);
311 319
312/* these defines must not be changed without changing the protocol version */ 320/* these defines must not be changed without changing the protocol version */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b9dcc50135c4..5d9112cefcd7 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -698,9 +698,15 @@ void drbd_thread_current_set_cpu(struct drbd_thread *thi)
698 */ 698 */
699unsigned int drbd_header_size(struct drbd_tconn *tconn) 699unsigned int drbd_header_size(struct drbd_tconn *tconn)
700{ 700{
701 BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95)); 701 if (tconn->agreed_pro_version >= 100) {
702 BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header80), 8)); 702 BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header100), 8));
703 return sizeof(struct p_header80); 703 return sizeof(struct p_header100);
704 } else {
705 BUILD_BUG_ON(sizeof(struct p_header80) !=
706 sizeof(struct p_header95));
707 BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header80), 8));
708 return sizeof(struct p_header80);
709 }
704} 710}
705 711
706static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size) 712static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size)
@@ -719,10 +725,24 @@ static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd,
719 return sizeof(struct p_header95); 725 return sizeof(struct p_header95);
720} 726}
721 727
722static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr, void *buffer, 728static unsigned int prepare_header100(struct p_header100 *h, enum drbd_packet cmd,
723 enum drbd_packet cmd, int size) 729 int size, int vnr)
730{
731 h->magic = cpu_to_be32(DRBD_MAGIC_100);
732 h->volume = cpu_to_be16(vnr);
733 h->command = cpu_to_be16(cmd);
734 h->length = cpu_to_be32(size);
735 h->pad = 0;
736 return sizeof(struct p_header100);
737}
738
739static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr,
740 void *buffer, enum drbd_packet cmd, int size)
724{ 741{
725 if (tconn->agreed_pro_version >= 95) 742 if (tconn->agreed_pro_version >= 100)
743 return prepare_header100(buffer, cmd, size, vnr);
744 else if (tconn->agreed_pro_version >= 95 &&
745 size > DRBD_MAX_SIZE_H80_PACKET)
726 return prepare_header95(buffer, cmd, size); 746 return prepare_header95(buffer, cmd, size);
727 else 747 else
728 return prepare_header80(buffer, cmd, size); 748 return prepare_header80(buffer, cmd, size);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index d9bb1a5c756a..0f52b88719c8 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2833,8 +2833,7 @@ int drbd_adm_add_minor(struct sk_buff *skb, struct genl_info *info)
2833 retcode = ERR_INVALID_REQUEST; 2833 retcode = ERR_INVALID_REQUEST;
2834 goto out; 2834 goto out;
2835 } 2835 }
2836 /* FIXME we need a define here */ 2836 if (adm_ctx.volume > DRBD_VOLUME_MAX) {
2837 if (adm_ctx.volume >= 256) {
2838 drbd_msg_put_info("requested volume id out of range"); 2837 drbd_msg_put_info("requested volume id out of range");
2839 retcode = ERR_INVALID_REQUEST; 2838 retcode = ERR_INVALID_REQUEST;
2840 goto out; 2839 goto out;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 7e0ab2246fb6..311b95453cb7 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -983,8 +983,18 @@ static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_i
983{ 983{
984 unsigned int header_size = drbd_header_size(tconn); 984 unsigned int header_size = drbd_header_size(tconn);
985 985
986 if (header_size == sizeof(struct p_header95) && 986 if (header_size == sizeof(struct p_header100) &&
987 *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) { 987 *(__be32 *)header == cpu_to_be32(DRBD_MAGIC_100)) {
988 struct p_header100 *h = header;
989 if (h->pad != 0) {
990 conn_err(tconn, "Header padding is not zero\n");
991 return -EINVAL;
992 }
993 pi->vnr = be16_to_cpu(h->volume);
994 pi->cmd = be16_to_cpu(h->command);
995 pi->size = be32_to_cpu(h->length);
996 } else if (header_size == sizeof(struct p_header95) &&
997 *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) {
988 struct p_header95 *h = header; 998 struct p_header95 *h = header;
989 999
990 pi->cmd = be16_to_cpu(h->command); 1000 pi->cmd = be16_to_cpu(h->command);