diff options
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 32 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 3 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 14 | ||||
-rw-r--r-- | include/linux/drbd.h | 1 | ||||
-rw-r--r-- | include/linux/drbd_genl.h | 2 | ||||
-rw-r--r-- | include/linux/drbd_limits.h | 2 |
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 { u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */ } __packed; +struct p_header100 { + u32 magic; + u16 volume; + u16 command; + u32 length; + u32 pad; +} __packed; + extern unsigned int drbd_header_size(struct drbd_tconn *tconn); /* 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) */ 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); + if (tconn->agreed_pro_version >= 100) { + BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header100), 8)); + return sizeof(struct p_header100); + } else { + 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 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, return sizeof(struct p_header95); } -static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr, void *buffer, - enum drbd_packet cmd, int size) +static unsigned int prepare_header100(struct p_header100 *h, enum drbd_packet cmd, + int size, int vnr) +{ + h->magic = cpu_to_be32(DRBD_MAGIC_100); + h->volume = cpu_to_be16(vnr); + h->command = cpu_to_be16(cmd); + h->length = cpu_to_be32(size); + h->pad = 0; + return sizeof(struct p_header100); +} + +static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr, + void *buffer, enum drbd_packet cmd, int size) { - if (tconn->agreed_pro_version >= 95) + if (tconn->agreed_pro_version >= 100) + return prepare_header100(buffer, cmd, size, vnr); + else if (tconn->agreed_pro_version >= 95 && + size > DRBD_MAX_SIZE_H80_PACKET) return prepare_header95(buffer, cmd, size); else 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) retcode = ERR_INVALID_REQUEST; goto out; } - /* FIXME we need a define here */ - if (adm_ctx.volume >= 256) { + if (adm_ctx.volume > DRBD_VOLUME_MAX) { drbd_msg_put_info("requested volume id out of range"); retcode = ERR_INVALID_REQUEST; 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 { unsigned int header_size = drbd_header_size(tconn); - if (header_size == sizeof(struct p_header95) && - *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) { + if (header_size == sizeof(struct p_header100) && + *(__be32 *)header == cpu_to_be32(DRBD_MAGIC_100)) { + struct p_header100 *h = header; + if (h->pad != 0) { + conn_err(tconn, "Header padding is not zero\n"); + return -EINVAL; + } + pi->vnr = be16_to_cpu(h->volume); + pi->cmd = be16_to_cpu(h->command); + pi->size = be32_to_cpu(h->length); + } else if (header_size == sizeof(struct p_header95) && + *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) { struct p_header95 *h = header; 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 { #define DRBD_MAGIC 0x83740267 #define DRBD_MAGIC_BIG 0x835a +#define DRBD_MAGIC_100 0x8620ec20 /* how I came up with this magic? * 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, * and/or the replication group (aka resource) name, * and the volume id within the resource. */ GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context, - /* currently only 256 volumes per group, - * but maybe we still change that */ __u32_field(1, GENLA_F_MANDATORY, ctx_volume) __str_field(2, GENLA_F_MANDATORY, ctx_conn_name, 128) ) 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 @@ #define DRBD_MINOR_COUNT_MAX 256 #define DRBD_MINOR_COUNT_DEF 32 +#define DRBD_VOLUME_MAX 65535 + #define DRBD_DIALOG_REFRESH_MIN 0 #define DRBD_DIALOG_REFRESH_MAX 600 |