aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/linux/drbd.h1
-rw-r--r--include/linux/drbd_genl.h2
-rw-r--r--include/linux/drbd_limits.h2
7 files changed, 50 insertions, 12 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);
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 60d308819096..fe8d6ba31bcb 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -341,6 +341,7 @@ enum drbd_timeout_flag {
341 341
342#define DRBD_MAGIC 0x83740267 342#define DRBD_MAGIC 0x83740267
343#define DRBD_MAGIC_BIG 0x835a 343#define DRBD_MAGIC_BIG 0x835a
344#define DRBD_MAGIC_100 0x8620ec20
344 345
345/* how I came up with this magic? 346/* how I came up with this magic?
346 * base64 decode "actlog==" ;) */ 347 * base64 decode "actlog==" ;) */
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 938e8560a833..10144d546a66 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -95,8 +95,6 @@ GENL_struct(DRBD_NLA_CFG_REPLY, 1, drbd_cfg_reply,
95 * and/or the replication group (aka resource) name, 95 * and/or the replication group (aka resource) name,
96 * and the volume id within the resource. */ 96 * and the volume id within the resource. */
97GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context, 97GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context,
98 /* currently only 256 volumes per group,
99 * but maybe we still change that */
100 __u32_field(1, GENLA_F_MANDATORY, ctx_volume) 98 __u32_field(1, GENLA_F_MANDATORY, ctx_volume)
101 __str_field(2, GENLA_F_MANDATORY, ctx_conn_name, 128) 99 __str_field(2, GENLA_F_MANDATORY, ctx_conn_name, 128)
102) 100)
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h
index 659a8eb38830..7f5149bef70e 100644
--- a/include/linux/drbd_limits.h
+++ b/include/linux/drbd_limits.h
@@ -19,6 +19,8 @@
19#define DRBD_MINOR_COUNT_MAX 256 19#define DRBD_MINOR_COUNT_MAX 256
20#define DRBD_MINOR_COUNT_DEF 32 20#define DRBD_MINOR_COUNT_DEF 32
21 21
22#define DRBD_VOLUME_MAX 65535
23
22#define DRBD_DIALOG_REFRESH_MIN 0 24#define DRBD_DIALOG_REFRESH_MIN 0
23#define DRBD_DIALOG_REFRESH_MAX 600 25#define DRBD_DIALOG_REFRESH_MAX 600
24 26