All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd
@ 2011-09-23 14:31 Philipp Reisner
  2011-09-23 14:31 ` [PATCH 01/10] drbd: drbd_send_ping(), drbd_send_ping(): Return 0 upon success and an error code otherwise Philipp Reisner
                   ` (9 more replies)
  0 siblings, 10 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

This the first request for review of drbd-8.4. The complete set has 
478 patches. This is the tenth installment containing 10 patches.

The whole set is available here:
  git://git.drbd.org/linux-2.6-drbd.git for-jens

and is jens_for-3.2_drivers...for-jens
and this part is a56df23^...ee04546

This patch series contains:
 * Introduces header 100, which allows 16 bit volume numbers.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 01/10] drbd: drbd_send_ping(), drbd_send_ping(): Return 0 upon success and an error code otherwise
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 14:31 ` [PATCH 02/10] drbd: Introduce new primitives for sending commands Philipp Reisner
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_main.c     |    4 ++--
 drivers/block/drbd/drbd_receiver.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a6459f7..7d7b30c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -768,13 +768,13 @@ int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
 int drbd_send_ping(struct drbd_tconn *tconn)
 {
 	struct p_header h;
-	return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING, &h, sizeof(h));
+	return conn_send_cmd(tconn, 0, &tconn->meta, P_PING, &h, sizeof(h));
 }
 
 int drbd_send_ping_ack(struct drbd_tconn *tconn)
 {
 	struct p_header h;
-	return !conn_send_cmd(tconn, 0, &tconn->meta, P_PING_ACK, &h, sizeof(h));
+	return conn_send_cmd(tconn, 0, &tconn->meta, P_PING_ACK, &h, sizeof(h));
 }
 
 int drbd_send_sync_param(struct drbd_conf *mdev)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6e6b829..6879082 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4501,7 +4501,7 @@ static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 
 static int got_Ping(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	return drbd_send_ping_ack(tconn);
+	return !drbd_send_ping_ack(tconn);
 
 }
 
@@ -4854,7 +4854,7 @@ int drbd_asender(struct drbd_thread *thi)
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(thi);
 		if (test_and_clear_bit(SEND_PING, &tconn->flags)) {
-			if (!drbd_send_ping(tconn)) {
+			if (drbd_send_ping(tconn)) {
 				conn_err(tconn, "drbd_send_ping has failed\n");
 				goto reconnect;
 			}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 02/10] drbd: Introduce new primitives for sending commands
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
  2011-09-23 14:31 ` [PATCH 01/10] drbd: drbd_send_ping(), drbd_send_ping(): Return 0 upon success and an error code otherwise Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 14:31 ` [PATCH 03/10] drbd: Introduce drbd_header_size() Philipp Reisner
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h  |    9 +++++
 drivers/block/drbd/drbd_main.c |   64 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 912ee5e..d61819f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1903,6 +1903,15 @@ static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
 	return drbd_send_cmd(mdev, &mdev->tconn->data, cmd, &h, sizeof(h));
 }
 
+extern void *conn_prepare_command(struct drbd_tconn *, struct drbd_socket *);
+extern void *drbd_prepare_command(struct drbd_conf *, struct drbd_socket *);
+extern int conn_send_command(struct drbd_tconn *, struct drbd_socket *,
+			     enum drbd_packet, unsigned int, void *,
+			     unsigned int);
+extern int drbd_send_command(struct drbd_conf *, struct drbd_socket *,
+			     enum drbd_packet, unsigned int, void *,
+			     unsigned int);
+
 extern int drbd_send_ping(struct drbd_tconn *tconn);
 extern int drbd_send_ping_ack(struct drbd_tconn *tconn);
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7d7b30c..c8384cd 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -765,6 +765,70 @@ int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
 	return err;
 }
 
+void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
+{
+	mutex_lock(&sock->mutex);
+	if (!sock->socket) {
+		mutex_unlock(&sock->mutex);
+		return NULL;
+	}
+	return sock->sbuf;
+}
+
+void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock)
+{
+	return conn_prepare_command(mdev->tconn, sock);
+}
+
+static int __send_command(struct drbd_tconn *tconn, int vnr,
+			  struct drbd_socket *sock, enum drbd_packet cmd,
+			  unsigned int header_size, void *data,
+			  unsigned int size)
+{
+	int msg_flags;
+	int err;
+
+	/*
+	 * Called with @data == NULL and the size of the data blocks in @size
+	 * for commands that send data blocks.  For those commands, omit the
+	 * MSG_MORE flag: this will increase the likelihood that data blocks
+	 * which are page aligned on the sender will end up page aligned on the
+	 * receiver.
+	 */
+	msg_flags = data ? MSG_MORE : 0;
+
+	_prepare_header(tconn, vnr, sock->sbuf, cmd,
+			header_size - sizeof(struct p_header) + size);
+	err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
+			    msg_flags);
+	if (data && !err)
+		err = drbd_send_all(tconn, sock->socket, data, size, 0);
+	return err;
+}
+
+int conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
+		      enum drbd_packet cmd, unsigned int header_size,
+		      void *data, unsigned int size)
+{
+	int err;
+
+	err = __send_command(tconn, 0, sock, cmd, header_size, data, size);
+	mutex_unlock(&sock->mutex);
+	return err;
+}
+
+int drbd_send_command(struct drbd_conf *mdev, struct drbd_socket *sock,
+		      enum drbd_packet cmd, unsigned int header_size,
+		      void *data, unsigned int size)
+{
+	int err;
+
+	err = __send_command(mdev->tconn, mdev->vnr, sock, cmd, header_size,
+			     data, size);
+	mutex_unlock(&sock->mutex);
+	return err;
+}
+
 int drbd_send_ping(struct drbd_tconn *tconn)
 {
 	struct p_header h;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 03/10] drbd: Introduce drbd_header_size()
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
  2011-09-23 14:31 ` [PATCH 01/10] drbd: drbd_send_ping(), drbd_send_ping(): Return 0 upon success and an error code otherwise Philipp Reisner
  2011-09-23 14:31 ` [PATCH 02/10] drbd: Introduce new primitives for sending commands Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 14:31 ` [PATCH 04/10] drbd: Replace and remove old primitives Philipp Reisner
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    2 ++
 drivers/block/drbd/drbd_main.c     |   14 ++++++++++++++
 drivers/block/drbd/drbd_receiver.c |    9 +++++----
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d61819f..29db016 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 c8384cd..b291d73 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 6879082..ceca24f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -998,7 +998,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;
 
@@ -4845,7 +4845,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! */
@@ -4929,7 +4930,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;
@@ -4953,7 +4954,7 @@ int drbd_asender(struct drbd_thread *thi)
 
 			buf	 = h;
 			received = 0;
-			expect	 = sizeof(struct p_header);
+			expect	 = header_size;
 			cmd	 = NULL;
 		}
 	}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 04/10] drbd: Replace and remove old primitives
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (2 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 03/10] drbd: Introduce drbd_header_size() Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 17:33   ` Kyle Moffett
  2011-09-23 14:31 ` [PATCH 05/10] drbd: Remove now-unused int_dig_out buffer Philipp Reisner
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   45 +----
 drivers/block/drbd/drbd_main.c     |  502 ++++++++++++++++--------------------
 drivers/block/drbd/drbd_receiver.c |   86 ++++---
 drivers/block/drbd/drbd_worker.c   |   24 +-
 4 files changed, 294 insertions(+), 363 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 29db016..e5dc772 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1060,22 +1060,6 @@ static inline struct drbd_conf *vnr_to_mdev(struct drbd_tconn *tconn, int vnr)
 	return (struct drbd_conf *)idr_find(&tconn->volumes, vnr);
 }
 
-static inline int drbd_get_data_sock(struct drbd_tconn *tconn)
-{
-	mutex_lock(&tconn->data.mutex);
-	if (!tconn->data.socket) {
-		/* Disconnected.  */
-		mutex_unlock(&tconn->data.mutex);
-		return -EIO;
-	}
-	return 0;
-}
-
-static inline void drbd_put_data_sock(struct drbd_tconn *tconn)
-{
-	mutex_unlock(&tconn->data.mutex);
-}
-
 /*
  * function declarations
  *************************/
@@ -1118,13 +1102,6 @@ extern int _conn_send_state_req(struct drbd_tconn *, int vnr, enum drbd_packet c
 				union drbd_state, union drbd_state);
 extern int _drbd_send_state(struct drbd_conf *mdev);
 extern int drbd_send_state(struct drbd_conf *mdev);
-extern int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct drbd_socket *sock,
-			  enum drbd_packet cmd, struct p_header *h, size_t size,
-			  unsigned msg_flags);
-extern int conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct drbd_socket *sock,
-			 enum drbd_packet cmd, struct p_header *h, size_t size);
-extern int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd,
-			  char *data, size_t size);
 extern int drbd_send_sync_param(struct drbd_conf *mdev);
 extern void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
 			    u32 set_size);
@@ -1149,7 +1126,7 @@ extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size)
 
 extern int drbd_send_bitmap(struct drbd_conf *mdev);
 extern void drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode);
-extern int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode);
+extern void conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode);
 extern void drbd_free_bc(struct drbd_backing_dev *ldev);
 extern void drbd_mdev_cleanup(struct drbd_conf *mdev);
 void drbd_print_uuids(struct drbd_conf *mdev, const char *text);
@@ -1885,26 +1862,6 @@ static inline void request_ping(struct drbd_tconn *tconn)
 	wake_asender(tconn);
 }
 
-static inline int _drbd_send_cmd(struct drbd_conf *mdev, struct drbd_socket *sock,
-				  enum drbd_packet cmd, struct p_header *h, size_t size,
-				  unsigned msg_flags)
-{
-	return _conn_send_cmd(mdev->tconn, mdev->vnr, sock, cmd, h, size, msg_flags);
-}
-
-static inline int drbd_send_cmd(struct drbd_conf *mdev, struct drbd_socket *sock,
-				enum drbd_packet cmd, struct p_header *h, size_t size)
-{
-	return conn_send_cmd(mdev->tconn, mdev->vnr, sock, cmd, h, size);
-}
-
-static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
-				      enum drbd_packet cmd)
-{
-	struct p_header h;
-	return drbd_send_cmd(mdev, &mdev->tconn->data, cmd, &h, sizeof(h));
-}
-
 extern void *conn_prepare_command(struct drbd_tconn *, struct drbd_socket *);
 extern void *drbd_prepare_command(struct drbd_conf *, struct drbd_socket *);
 extern int conn_send_command(struct drbd_tconn *, struct drbd_socket *,
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b291d73..4aec4af 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -717,8 +717,8 @@ static void prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int siz
 	h->vol_n_len = cpu_to_be32(vnr << 24 | size);
 }
 
-static void _prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h,
-			    enum drbd_packet cmd, int size)
+static void prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h,
+			   enum drbd_packet cmd, int size)
 {
 	if (tconn->agreed_pro_version >= 95)
 		prepare_header95(&h->h95, cmd, size, vnr);
@@ -726,59 +726,6 @@ static void _prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *
 		prepare_header80(&h->h80, cmd, size);
 }
 
-static void prepare_header(struct drbd_conf *mdev, struct p_header *h,
-			   enum drbd_packet cmd, int size)
-{
-	_prepare_header(mdev->tconn, mdev->vnr, h, cmd, size);
-}
-
-/* the appropriate socket mutex must be held already */
-int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct drbd_socket *sock,
-		   enum drbd_packet cmd, struct p_header *h, size_t size,
-		   unsigned msg_flags)
-{
-	int err;
-
-	_prepare_header(tconn, vnr, h, cmd, size - sizeof(struct p_header));
-	err = drbd_send_all(tconn, sock->socket, h, size, msg_flags);
-	if (err && !signal_pending(current))
-		conn_warn(tconn, "short send %s size=%d\n",
-			  cmdname(cmd), (int)size);
-	return err;
-}
-
-/* don't pass the socket. we may only look at it
- * when we hold the appropriate socket mutex.
- */
-int conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct drbd_socket *sock,
-		  enum drbd_packet cmd, struct p_header *h, size_t size)
-{
-	int err = -EIO;
-
-	mutex_lock(&sock->mutex);
-	if (sock->socket)
-		err = _conn_send_cmd(tconn, vnr, sock, cmd, h, size, 0);
-	mutex_unlock(&sock->mutex);
-	return err;
-}
-
-int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
-		   size_t size)
-{
-	struct p_header80 h;
-	int err;
-
-	prepare_header80(&h, cmd, size);
-	err = drbd_get_data_sock(tconn);
-	if (!err) {
-		err = drbd_send_all(tconn, tconn->data.socket, &h, sizeof(h), 0);
-		if (!err)
-			err = drbd_send_all(tconn, tconn->data.socket, data, size, 0);
-		drbd_put_data_sock(tconn);
-	}
-	return err;
-}
-
 void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
 {
 	mutex_lock(&sock->mutex);
@@ -811,8 +758,8 @@ static int __send_command(struct drbd_tconn *tconn, int vnr,
 	 */
 	msg_flags = data ? MSG_MORE : 0;
 
-	_prepare_header(tconn, vnr, sock->sbuf, cmd,
-			header_size - sizeof(struct p_header) + size);
+	prepare_header(tconn, vnr, sock->sbuf, cmd,
+		       header_size - sizeof(struct p_header) + size);
 	err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
 			    msg_flags);
 	if (data && !err)
@@ -845,22 +792,36 @@ int drbd_send_command(struct drbd_conf *mdev, struct drbd_socket *sock,
 
 int drbd_send_ping(struct drbd_tconn *tconn)
 {
-	struct p_header h;
-	return conn_send_cmd(tconn, 0, &tconn->meta, P_PING, &h, sizeof(h));
+	struct drbd_socket *sock;
+
+	sock = &tconn->meta;
+	if (!conn_prepare_command(tconn, sock))
+		return -EIO;
+	return conn_send_command(tconn, sock, P_PING, sizeof(struct p_header), NULL, 0);
 }
 
 int drbd_send_ping_ack(struct drbd_tconn *tconn)
 {
-	struct p_header h;
-	return conn_send_cmd(tconn, 0, &tconn->meta, P_PING_ACK, &h, sizeof(h));
+	struct drbd_socket *sock;
+
+	sock = &tconn->meta;
+	if (!conn_prepare_command(tconn, sock))
+		return -EIO;
+	return conn_send_command(tconn, sock, P_PING_ACK, sizeof(struct p_header), NULL, 0);
 }
 
 int drbd_send_sync_param(struct drbd_conf *mdev)
 {
-	struct p_rs_param_95 *p;
 	struct drbd_socket *sock;
-	int size, err;
+	struct p_rs_param_95 *p;
+	int size;
 	const int apv = mdev->tconn->agreed_pro_version;
+	enum drbd_packet cmd;
+
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
 
 	size = apv <= 87 ? sizeof(struct p_rs_param)
 		: apv == 88 ? sizeof(struct p_rs_param)
@@ -868,112 +829,96 @@ int drbd_send_sync_param(struct drbd_conf *mdev)
 		: apv <= 94 ? sizeof(struct p_rs_param_89)
 		: /* apv >= 95 */ sizeof(struct p_rs_param_95);
 
-	mutex_lock(&mdev->tconn->data.mutex);
-	sock = &mdev->tconn->data;
-
-	if (likely(sock->socket != NULL)) {
-		enum drbd_packet cmd =
-			apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
-
-		p = mdev->tconn->data.sbuf;
-
-		/* initialize verify_alg and csums_alg */
-		memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
-
-		if (get_ldev(mdev)) {
-			p->rate = cpu_to_be32(mdev->ldev->dc.resync_rate);
-			p->c_plan_ahead = cpu_to_be32(mdev->ldev->dc.c_plan_ahead);
-			p->c_delay_target = cpu_to_be32(mdev->ldev->dc.c_delay_target);
-			p->c_fill_target = cpu_to_be32(mdev->ldev->dc.c_fill_target);
-			p->c_max_rate = cpu_to_be32(mdev->ldev->dc.c_max_rate);
-			put_ldev(mdev);
-		} else {
-			p->rate = cpu_to_be32(DRBD_RATE_DEF);
-			p->c_plan_ahead = cpu_to_be32(DRBD_C_PLAN_AHEAD_DEF);
-			p->c_delay_target = cpu_to_be32(DRBD_C_DELAY_TARGET_DEF);
-			p->c_fill_target = cpu_to_be32(DRBD_C_FILL_TARGET_DEF);
-			p->c_max_rate = cpu_to_be32(DRBD_C_MAX_RATE_DEF);
-		}
+	cmd = apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
 
-		if (apv >= 88)
-			strcpy(p->verify_alg, mdev->tconn->net_conf->verify_alg);
-		if (apv >= 89)
-			strcpy(p->csums_alg, mdev->tconn->net_conf->csums_alg);
+	/* initialize verify_alg and csums_alg */
+	memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
 
-		err = _drbd_send_cmd(mdev, sock, cmd, &p->head, size, 0);
-	} else
-		err = -EIO;
+	if (get_ldev(mdev)) {
+		p->rate = cpu_to_be32(mdev->ldev->dc.resync_rate);
+		p->c_plan_ahead = cpu_to_be32(mdev->ldev->dc.c_plan_ahead);
+		p->c_delay_target = cpu_to_be32(mdev->ldev->dc.c_delay_target);
+		p->c_fill_target = cpu_to_be32(mdev->ldev->dc.c_fill_target);
+		p->c_max_rate = cpu_to_be32(mdev->ldev->dc.c_max_rate);
+		put_ldev(mdev);
+	} else {
+		p->rate = cpu_to_be32(DRBD_RATE_DEF);
+		p->c_plan_ahead = cpu_to_be32(DRBD_C_PLAN_AHEAD_DEF);
+		p->c_delay_target = cpu_to_be32(DRBD_C_DELAY_TARGET_DEF);
+		p->c_fill_target = cpu_to_be32(DRBD_C_FILL_TARGET_DEF);
+		p->c_max_rate = cpu_to_be32(DRBD_C_MAX_RATE_DEF);
+	}
 
-	mutex_unlock(&mdev->tconn->data.mutex);
+	if (apv >= 88)
+		strcpy(p->verify_alg, mdev->tconn->net_conf->verify_alg);
+	if (apv >= 89)
+		strcpy(p->csums_alg, mdev->tconn->net_conf->csums_alg);
 
-	return err;
+	return drbd_send_command(mdev, sock, cmd, size, NULL, 0);
 }
 
 int drbd_send_protocol(struct drbd_tconn *tconn)
 {
+	struct drbd_socket *sock;
 	struct p_protocol *p;
-	int size, cf, err;
+	int size, cf;
+
+	if (tconn->net_conf->dry_run && tconn->agreed_pro_version < 92) {
+		conn_err(tconn, "--dry-run is not supported by peer");
+		return -EOPNOTSUPP;
+	}
 
-	size = sizeof(struct p_protocol);
+	sock = &tconn->data;
+	p = conn_prepare_command(tconn, sock);
+	if (!p)
+		return -EIO;
 
+	size = sizeof(*p);
 	if (tconn->agreed_pro_version >= 87)
 		size += strlen(tconn->net_conf->integrity_alg) + 1;
 
-	/* we must not recurse into our own queue,
-	 * as that is blocked during handshake */
-	p = kmalloc(size, GFP_NOIO);
-	if (p == NULL)
-		return -ENOMEM;
-
 	p->protocol      = cpu_to_be32(tconn->net_conf->wire_protocol);
 	p->after_sb_0p   = cpu_to_be32(tconn->net_conf->after_sb_0p);
 	p->after_sb_1p   = cpu_to_be32(tconn->net_conf->after_sb_1p);
 	p->after_sb_2p   = cpu_to_be32(tconn->net_conf->after_sb_2p);
 	p->two_primaries = cpu_to_be32(tconn->net_conf->two_primaries);
-
 	cf = 0;
 	if (tconn->net_conf->want_lose)
 		cf |= CF_WANT_LOSE;
-	if (tconn->net_conf->dry_run) {
-		if (tconn->agreed_pro_version >= 92)
-			cf |= CF_DRY_RUN;
-		else {
-			conn_err(tconn, "--dry-run is not supported by peer");
-			kfree(p);
-			return -EOPNOTSUPP;
-		}
-	}
+	if (tconn->net_conf->dry_run)
+		cf |= CF_DRY_RUN;
 	p->conn_flags    = cpu_to_be32(cf);
 
 	if (tconn->agreed_pro_version >= 87)
 		strcpy(p->integrity_alg, tconn->net_conf->integrity_alg);
-
-	err = conn_send_cmd2(tconn, P_PROTOCOL, p->head.payload, size - sizeof(struct p_header));
-	kfree(p);
-	return err;
+	return conn_send_command(tconn, sock, P_PROTOCOL, size, NULL, 0);
 }
 
 int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags)
 {
-	struct p_uuids p;
+	struct drbd_socket *sock;
+	struct p_uuids *p;
 	int i;
 
 	if (!get_ldev_if_state(mdev, D_NEGOTIATING))
 		return 0;
 
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
 	for (i = UI_CURRENT; i < UI_SIZE; i++)
-		p.uuid[i] = mdev->ldev ? cpu_to_be64(mdev->ldev->md.uuid[i]) : 0;
+		p->uuid[i] = mdev->ldev ? cpu_to_be64(mdev->ldev->md.uuid[i]) : 0;
 
 	mdev->comm_bm_set = drbd_bm_total_weight(mdev);
-	p.uuid[UI_SIZE] = cpu_to_be64(mdev->comm_bm_set);
+	p->uuid[UI_SIZE] = cpu_to_be64(mdev->comm_bm_set);
 	uuid_flags |= mdev->tconn->net_conf->want_lose ? 1 : 0;
 	uuid_flags |= test_bit(CRASHED_PRIMARY, &mdev->flags) ? 2 : 0;
 	uuid_flags |= mdev->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
-	p.uuid[UI_FLAGS] = cpu_to_be64(uuid_flags);
+	p->uuid[UI_FLAGS] = cpu_to_be64(uuid_flags);
 
 	put_ldev(mdev);
-
-	return drbd_send_cmd(mdev, &mdev->tconn->data, P_UUIDS, &p.head, sizeof(p));
+	return drbd_send_command(mdev, sock, P_UUIDS, sizeof(*p), NULL, 0);
 }
 
 int drbd_send_uuids(struct drbd_conf *mdev)
@@ -1006,7 +951,8 @@ void drbd_print_uuids(struct drbd_conf *mdev, const char *text)
 
 void drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev)
 {
-	struct p_rs_uuid p;
+	struct drbd_socket *sock;
+	struct p_rs_uuid *p;
 	u64 uuid;
 
 	D_ASSERT(mdev->state.disk == D_UP_TO_DATE);
@@ -1015,14 +961,19 @@ void drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev)
 	drbd_uuid_set(mdev, UI_BITMAP, uuid);
 	drbd_print_uuids(mdev, "updated sync UUID");
 	drbd_md_sync(mdev);
-	p.uuid = cpu_to_be64(uuid);
 
-	drbd_send_cmd(mdev, &mdev->tconn->data, P_SYNC_UUID, &p.head, sizeof(p));
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (p) {
+		p->uuid = cpu_to_be64(uuid);
+		drbd_send_command(mdev, sock, P_SYNC_UUID, sizeof(*p), NULL, 0);
+	}
 }
 
 int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags)
 {
-	struct p_sizes p;
+	struct drbd_socket *sock;
+	struct p_sizes *p;
 	sector_t d_size, u_size;
 	int q_order_type, max_bio_size;
 
@@ -1041,14 +992,17 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl
 		max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
 	}
 
-	p.d_size = cpu_to_be64(d_size);
-	p.u_size = cpu_to_be64(u_size);
-	p.c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev));
-	p.max_bio_size = cpu_to_be32(max_bio_size);
-	p.queue_order_type = cpu_to_be16(q_order_type);
-	p.dds_flags = cpu_to_be16(flags);
-
-	return drbd_send_cmd(mdev, &mdev->tconn->data, P_SIZES, &p.head, sizeof(p));
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->d_size = cpu_to_be64(d_size);
+	p->u_size = cpu_to_be64(u_size);
+	p->c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev));
+	p->max_bio_size = cpu_to_be32(max_bio_size);
+	p->queue_order_type = cpu_to_be16(q_order_type);
+	p->dds_flags = cpu_to_be16(flags);
+	return drbd_send_command(mdev, sock, P_SIZES, sizeof(*p), NULL, 0);
 }
 
 /**
@@ -1058,50 +1012,56 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl
 int drbd_send_state(struct drbd_conf *mdev)
 {
 	struct drbd_socket *sock;
-	struct p_state p;
-	int err = -EIO;
+	struct p_state *p;
 
-	mutex_lock(&mdev->tconn->data.mutex);
-
-	p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */
 	sock = &mdev->tconn->data;
-
-	if (likely(sock->socket != NULL))
-		err = _drbd_send_cmd(mdev, sock, P_STATE, &p.head, sizeof(p), 0);
-
-	mutex_unlock(&mdev->tconn->data.mutex);
-
-	return err;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->state = cpu_to_be32(mdev->state.i); /* Within the send mutex */
+	return drbd_send_command(mdev, sock, P_STATE, sizeof(*p), NULL, 0);
 }
 
 int _conn_send_state_req(struct drbd_tconn *tconn, int vnr, enum drbd_packet cmd,
 			 union drbd_state mask, union drbd_state val)
 {
-	struct p_req_state p;
-
-	p.mask    = cpu_to_be32(mask.i);
-	p.val     = cpu_to_be32(val.i);
+	struct drbd_socket *sock;
+	struct p_req_state *p;
 
-	return conn_send_cmd(tconn, vnr, &tconn->data, cmd, &p.head, sizeof(p));
+	sock = &tconn->data;
+	p = conn_prepare_command(tconn, sock);
+	if (!p)
+		return -EIO;
+	p->mask = cpu_to_be32(mask.i);
+	p->val = cpu_to_be32(val.i);
+	return conn_send_command(tconn, sock, cmd, sizeof(*p), NULL, 0);
 }
 
 void drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode)
 {
-	struct p_req_state_reply p;
-
-	p.retcode    = cpu_to_be32(retcode);
+	struct drbd_socket *sock;
+	struct p_req_state_reply *p;
 
-	drbd_send_cmd(mdev, &mdev->tconn->meta, P_STATE_CHG_REPLY, &p.head, sizeof(p));
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (p) {
+		p->retcode = cpu_to_be32(retcode);
+		drbd_send_command(mdev, sock, P_STATE_CHG_REPLY, sizeof(*p), NULL, 0);
+	}
 }
 
-int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
+void conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
 {
-	struct p_req_state_reply p;
+	struct drbd_socket *sock;
+	struct p_req_state_reply *p;
 	enum drbd_packet cmd = tconn->agreed_pro_version < 100 ? P_STATE_CHG_REPLY : P_CONN_ST_CHG_REPLY;
 
-	p.retcode    = cpu_to_be32(retcode);
-
-	return !conn_send_cmd(tconn, 0, &tconn->meta, cmd, &p.head, sizeof(p));
+	sock = &tconn->data;
+	p = conn_prepare_command(tconn, sock);
+	if (p) {
+		p->retcode = cpu_to_be32(retcode);
+		conn_send_command(tconn, sock, cmd, sizeof(*p), NULL, 0);
+	}
 }
 
 static void dcbp_set_code(struct p_compressed_bm *p, enum drbd_bitmap_code code)
@@ -1224,21 +1184,20 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
 static int
 send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 {
-	struct p_compressed_bm *p = mdev->tconn->data.sbuf;
+	struct drbd_socket *sock = &mdev->tconn->data;
+	struct p_compressed_bm *p = sock->sbuf;
 	unsigned long num_words;
 	int len, err;
 
 	len = fill_bitmap_rle_bits(mdev, p, c);
-
 	if (len < 0)
 		return -EIO;
 
 	if (len) {
 		dcbp_set_code(p, RLE_VLI_Bits);
-		err = _drbd_send_cmd(mdev, &mdev->tconn->data,
-				     P_COMPRESSED_BITMAP, &p->head,
-				     sizeof(*p) + len, 0);
-
+		err = __send_command(mdev->tconn, mdev->vnr, sock,
+				     P_COMPRESSED_BITMAP, sizeof(*p) + len,
+				     NULL, 0);
 		c->packets[0]++;
 		c->bytes[0] += sizeof(*p) + len;
 
@@ -1247,14 +1206,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 	} else {
 		/* was not compressible.
 		 * send a buffer full of plain text bits instead. */
-		struct p_header *h = mdev->tconn->data.sbuf;
+		struct p_header *h = sock->sbuf;
 		num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
 		len = num_words * sizeof(long);
 		if (len)
 			drbd_bm_get_lel(mdev, c->word_offset, num_words,
 					(unsigned long *)h->payload);
-		err = _drbd_send_cmd(mdev, &mdev->tconn->data, P_BITMAP,
-				     h, sizeof(struct p_header80) + len, 0);
+		err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP,
+				     sizeof(*h) + len, NULL, 0);
 		c->word_offset += num_words;
 		c->bit_offset = c->word_offset * BITS_PER_LONG;
 
@@ -1314,23 +1273,28 @@ static int _drbd_send_bitmap(struct drbd_conf *mdev)
 
 int drbd_send_bitmap(struct drbd_conf *mdev)
 {
-	int err;
+	struct drbd_socket *sock = &mdev->tconn->data;
+	int err = -1;
 
-	if (drbd_get_data_sock(mdev->tconn))
-		return -1;
-	err = !_drbd_send_bitmap(mdev);
-	drbd_put_data_sock(mdev->tconn);
+	mutex_lock(&sock->mutex);
+	if (sock->socket)
+		err = !_drbd_send_bitmap(mdev);
+	mutex_unlock(&sock->mutex);
 	return err;
 }
+
 void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
 {
-	struct p_barrier_ack p;
-
-	p.barrier  = barrier_nr;
-	p.set_size = cpu_to_be32(set_size);
+	struct drbd_socket *sock;
+	struct p_barrier_ack *p;
 
-	if (mdev->state.conn >= C_CONNECTED)
-		drbd_send_cmd(mdev, &mdev->tconn->meta, P_BARRIER_ACK, &p.head, sizeof(p));
+	sock = &mdev->tconn->meta;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p || mdev->state.conn < C_CONNECTED)
+		return;
+	p->barrier = barrier_nr;
+	p->set_size = cpu_to_be32(set_size);
+	drbd_send_command(mdev, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0);
 }
 
 /**
@@ -1344,16 +1308,18 @@ void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
 static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
 			  u64 sector, u32 blksize, u64 block_id)
 {
-	struct p_block_ack p;
-
-	p.sector   = sector;
-	p.block_id = block_id;
-	p.blksize  = blksize;
-	p.seq_num  = cpu_to_be32(atomic_inc_return(&mdev->packet_seq));
+	struct drbd_socket *sock;
+	struct p_block_ack *p;
 
-	if (!mdev->tconn->meta.socket || mdev->state.conn < C_CONNECTED)
+	sock = &mdev->tconn->meta;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p || mdev->state.conn < C_CONNECTED)
 		return -EIO;
-	return drbd_send_cmd(mdev, &mdev->tconn->meta, cmd, &p.head, sizeof(p));
+	p->sector = sector;
+	p->block_id = block_id;
+	p->blksize = blksize;
+	p->seq_num = cpu_to_be32(atomic_inc_return(&mdev->packet_seq));
+	return drbd_send_command(mdev, sock, cmd, sizeof(*p), NULL, 0);
 }
 
 /* dp->sector and dp->block_id already/still in network byte order,
@@ -1403,45 +1369,51 @@ int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packet cmd,
 int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
 		       sector_t sector, int size, u64 block_id)
 {
-	struct p_block_req p;
-
-	p.sector   = cpu_to_be64(sector);
-	p.block_id = block_id;
-	p.blksize  = cpu_to_be32(size);
+	struct drbd_socket *sock;
+	struct p_block_req *p;
 
-	return drbd_send_cmd(mdev, &mdev->tconn->data, cmd, &p.head, sizeof(p));
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(sector);
+	p->block_id = block_id;
+	p->blksize = cpu_to_be32(size);
+	return drbd_send_command(mdev, sock, cmd, sizeof(*p), NULL, 0);
 }
 
 int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector, int size,
 			    void *digest, int digest_size, enum drbd_packet cmd)
 {
-	int err;
-	struct p_block_req p;
+	struct drbd_socket *sock;
+	struct p_block_req *p;
 
-	prepare_header(mdev, &p.head, cmd, sizeof(p) - sizeof(struct p_header) + digest_size);
-	p.sector   = cpu_to_be64(sector);
-	p.block_id = ID_SYNCER /* unused */;
-	p.blksize  = cpu_to_be32(size);
+	/* FIXME: Put the digest into the preallocated socket buffer.  */
 
-	mutex_lock(&mdev->tconn->data.mutex);
-	err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, &p, sizeof(p), 0);
-	if (!err)
-		err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, digest, digest_size, 0);
-	mutex_unlock(&mdev->tconn->data.mutex);
-	return err;
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(sector);
+	p->block_id = ID_SYNCER /* unused */;
+	p->blksize = cpu_to_be32(size);
+	return drbd_send_command(mdev, sock, P_STATE_CHG_REPLY, sizeof(*p),
+				 digest, digest_size);
 }
 
 int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size)
 {
-	int ok;
-	struct p_block_req p;
-
-	p.sector   = cpu_to_be64(sector);
-	p.block_id = ID_SYNCER /* unused */;
-	p.blksize  = cpu_to_be32(size);
+	struct drbd_socket *sock;
+	struct p_block_req *p;
 
-	ok = !drbd_send_cmd(mdev, &mdev->tconn->data, P_OV_REQUEST, &p.head, sizeof(p));
-	return ok;
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(sector);
+	p->block_id = ID_SYNCER /* unused */;
+	p->blksize = cpu_to_be32(size);
+	return drbd_send_command(mdev, sock, P_OV_REQUEST, sizeof(*p), NULL, 0);
 }
 
 /* called on sndtimeo
@@ -1634,39 +1606,30 @@ static u32 bio_flags_to_wire(struct drbd_conf *mdev, unsigned long bi_rw)
  */
 int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 {
-	int err;
-	struct p_data p;
+	struct drbd_socket *sock;
+	struct p_data *p;
 	unsigned int dp_flags = 0;
-	void *dgb;
 	int dgs;
-
-	err = drbd_get_data_sock(mdev->tconn);
-	if (err)
-		return err;
+	int err;
 
 	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
-	prepare_header(mdev, &p.head, P_DATA, sizeof(p) - sizeof(struct p_header) + dgs + req->i.size);
-	p.sector   = cpu_to_be64(req->i.sector);
-	p.block_id = (unsigned long)req;
-	p.seq_num  = cpu_to_be32(req->seq_num = atomic_inc_return(&mdev->packet_seq));
-
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(req->i.sector);
+	p->block_id = (unsigned long)req;
+	p->seq_num = cpu_to_be32(req->seq_num = atomic_inc_return(&mdev->packet_seq));
 	dp_flags = bio_flags_to_wire(mdev, req->master_bio->bi_rw);
-
 	if (mdev->state.conn >= C_SYNC_SOURCE &&
 	    mdev->state.conn <= C_PAUSED_SYNC_T)
 		dp_flags |= DP_MAY_SET_IN_SYNC;
-
-	p.dp_flags = cpu_to_be32(dp_flags);
-	set_bit(UNPLUG_REMOTE, &mdev->flags);
-	err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, &p,
-			    sizeof(p), dgs ? MSG_MORE : 0);
-	if (!err && dgs) {
-		dgb = mdev->tconn->int_dig_out;
-		drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, dgb);
-		err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, dgb, dgs, 0);
-	}
+	p->dp_flags = cpu_to_be32(dp_flags);
+	if (dgs)
+		drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, p + 1);
+	err = __send_command(mdev->tconn, mdev->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
 	if (!err) {
 		/* For protocol A, we have to memcpy the payload into
 		 * socket buffers, as we may complete right away
@@ -1690,7 +1653,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 			 * currently supported in kernel crypto. */
 			unsigned char digest[64];
 			drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, digest);
-			if (memcmp(mdev->tconn->int_dig_out, digest, dgs)) {
+			if (memcmp(p + 1, digest, dgs)) {
 				dev_warn(DEV,
 					"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
 					(unsigned long long)req->i.sector, req->i.size);
@@ -1699,8 +1662,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 		     ... Be noisy about digest too large ...
 		} */
 	}
-
-	drbd_put_data_sock(mdev->tconn);
+	mutex_unlock(&sock->mutex);  /* locked by drbd_prepare_command() */
 
 	return err;
 }
@@ -1712,51 +1674,43 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 		    struct drbd_peer_request *peer_req)
 {
+	struct drbd_socket *sock;
+	struct p_data *p;
 	int err;
-	struct p_data p;
-	void *dgb;
 	int dgs;
 
 	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
-	prepare_header(mdev, &p.head, cmd, sizeof(p) -
-					   sizeof(struct p_header80) +
-					   dgs + peer_req->i.size);
-	p.sector   = cpu_to_be64(peer_req->i.sector);
-	p.block_id = peer_req->block_id;
-	p.seq_num = 0;  /* unused */
-
-	/* Only called by our kernel thread.
-	 * This one may be interrupted by DRBD_SIG and/or DRBD_SIGKILL
-	 * in response to admin command or module unload.
-	 */
-	err = drbd_get_data_sock(mdev->tconn);
-	if (err)
-		return err;
-	err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, &p,
-			    sizeof(p), dgs ? MSG_MORE : 0);
-	if (!err && dgs) {
-		dgb = mdev->tconn->int_dig_out;
-		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, peer_req, dgb);
-		err = drbd_send_all(mdev->tconn, mdev->tconn->data.socket, dgb,
-				    dgs, 0);
-	}
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(peer_req->i.sector);
+	p->block_id = peer_req->block_id;
+	p->seq_num = 0;  /* unused */
+	if (dgs)
+		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, peer_req, p + 1);
+	err = __send_command(mdev->tconn, mdev->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
 	if (!err)
 		err = _drbd_send_zc_ee(mdev, peer_req);
-	drbd_put_data_sock(mdev->tconn);
+	mutex_unlock(&sock->mutex);  /* locked by drbd_prepare_command() */
 
 	return err;
 }
 
 int drbd_send_out_of_sync(struct drbd_conf *mdev, struct drbd_request *req)
 {
-	struct p_block_desc p;
-
-	p.sector  = cpu_to_be64(req->i.sector);
-	p.blksize = cpu_to_be32(req->i.size);
+	struct drbd_socket *sock;
+	struct p_block_desc *p;
 
-	return drbd_send_cmd(mdev, &mdev->tconn->data, P_OUT_OF_SYNC, &p.head, sizeof(p));
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
+	p->sector = cpu_to_be64(req->i.sector);
+	p->blksize = cpu_to_be32(req->i.size);
+	return drbd_send_command(mdev, sock, P_OUT_OF_SYNC, sizeof(*p), NULL, 0);
 }
 
 /*
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index ceca24f..1270af3 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -729,24 +729,32 @@ out:
 	return s_estab;
 }
 
-static int drbd_send_fp(struct drbd_tconn *tconn, struct drbd_socket *sock, enum drbd_packet cmd)
-{
-	struct p_header *h = tconn->data.sbuf;
+static int decode_header(struct drbd_tconn *, struct p_header *, struct packet_info *);
 
-	return !_conn_send_cmd(tconn, 0, sock, cmd, h, sizeof(*h), 0);
+static int send_first_packet(struct drbd_tconn *tconn, struct drbd_socket *sock,
+			     enum drbd_packet cmd)
+{
+	if (!conn_prepare_command(tconn, sock))
+		return -EIO;
+	return conn_send_command(tconn, sock, cmd, sizeof(struct p_header), NULL, 0);
 }
 
-static enum drbd_packet drbd_recv_fp(struct drbd_tconn *tconn, struct socket *sock)
+static int receive_first_packet(struct drbd_tconn *tconn, struct socket *sock)
 {
-	struct p_header80 h;
-	int rr;
-
-	rr = drbd_recv_short(sock, &h, sizeof(h), 0);
-
-	if (rr == sizeof(h) && h.magic == cpu_to_be32(DRBD_MAGIC))
-		return be16_to_cpu(h.command);
+	unsigned int header_size = drbd_header_size(tconn);
+	struct packet_info pi;
+	int err;
 
-	return 0xffff;
+	err = drbd_recv_short(sock, tconn->data.rbuf, header_size, 0);
+	if (err != header_size) {
+		if (err >= 0)
+			err = -EIO;
+		return err;
+	}
+	err = decode_header(tconn, tconn->data.rbuf, &pi);
+	if (err)
+		return err;
+	return pi.cmd;
 }
 
 /**
@@ -834,10 +842,10 @@ static int drbd_connect(struct drbd_tconn *tconn)
 		if (s) {
 			if (!tconn->data.socket) {
 				tconn->data.socket = s;
-				drbd_send_fp(tconn, &tconn->data, P_INITIAL_DATA);
+				send_first_packet(tconn, &tconn->data, P_INITIAL_DATA);
 			} else if (!tconn->meta.socket) {
 				tconn->meta.socket = s;
-				drbd_send_fp(tconn, &tconn->meta, P_INITIAL_META);
+				send_first_packet(tconn, &tconn->meta, P_INITIAL_META);
 			} else {
 				conn_err(tconn, "Logic error in drbd_connect()\n");
 				goto out_release_sockets;
@@ -855,7 +863,7 @@ static int drbd_connect(struct drbd_tconn *tconn)
 retry:
 		s = drbd_wait_for_connect(tconn);
 		if (s) {
-			try = drbd_recv_fp(tconn, s);
+			try = receive_first_packet(tconn, s);
 			drbd_socket_okay(&tconn->data.socket);
 			drbd_socket_okay(&tconn->meta.socket);
 			switch (try) {
@@ -1327,6 +1335,10 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 
 	if (dgs) {
+		/*
+		 * FIXME: Receive the incoming digest into the receive buffer
+		 *	  here, together with its struct p_data?
+		 */
 		err = drbd_recv_all_warn(mdev->tconn, dig_in, dgs);
 		if (err)
 			return NULL;
@@ -4182,27 +4194,17 @@ static int drbd_disconnected(int vnr, void *p, void *data)
  */
 static int drbd_send_features(struct drbd_tconn *tconn)
 {
-	/* ASSERT current == mdev->tconn->receiver ... */
-	struct p_connection_features *p = tconn->data.sbuf;
-	int err;
-
-	if (mutex_lock_interruptible(&tconn->data.mutex)) {
-		conn_err(tconn, "interrupted during initial handshake\n");
-		return -EINTR;
-	}
+	struct drbd_socket *sock;
+	struct p_connection_features *p;
 
-	if (tconn->data.socket == NULL) {
-		mutex_unlock(&tconn->data.mutex);
+	sock = &tconn->data;
+	p = conn_prepare_command(tconn, sock);
+	if (!p)
 		return -EIO;
-	}
-
 	memset(p, 0, sizeof(*p));
 	p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
 	p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
-	err = _conn_send_cmd(tconn, 0, &tconn->data, P_CONNECTION_FEATURES,
-			     &p->head, sizeof(*p), 0);
-	mutex_unlock(&tconn->data.mutex);
-	return err;
+	return conn_send_command(tconn, sock, P_CONNECTION_FEATURES, sizeof(*p), NULL, 0);
 }
 
 /*
@@ -4286,6 +4288,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 
 static int drbd_do_auth(struct drbd_tconn *tconn)
 {
+	struct drbd_socket *sock;
 	char my_challenge[CHALLENGE_LEN];  /* 64 Bytes... */
 	struct scatterlist sg;
 	char *response = NULL;
@@ -4297,6 +4300,8 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 	struct packet_info pi;
 	int err, rv;
 
+	/* FIXME: Put the challenge/response into the preallocated socket buffer.  */
+
 	desc.tfm = tconn->cram_hmac_tfm;
 	desc.flags = 0;
 
@@ -4310,7 +4315,14 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 
 	get_random_bytes(my_challenge, CHALLENGE_LEN);
 
-	rv = !conn_send_cmd2(tconn, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
+	sock = &tconn->data;
+	if (!conn_prepare_command(tconn, sock)) {
+		rv = 0;
+		goto fail;
+	}
+	rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE,
+				sizeof(struct p_header),
+				my_challenge, CHALLENGE_LEN);
 	if (!rv)
 		goto fail;
 
@@ -4364,7 +4376,13 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 		goto fail;
 	}
 
-	rv = !conn_send_cmd2(tconn, P_AUTH_RESPONSE, response, resp_size);
+	if (!conn_prepare_command(tconn, sock)) {
+		rv = 0;
+		goto fail;
+	}
+	rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE,
+				sizeof(struct p_header),
+				response, resp_size);
 	if (!rv)
 		goto fail;
 
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 8059ea3..6feaa4a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1193,10 +1193,10 @@ int w_prev_work_done(struct drbd_work *w, int cancel)
 
 int w_send_barrier(struct drbd_work *w, int cancel)
 {
+	struct drbd_socket *sock;
 	struct drbd_tl_epoch *b = container_of(w, struct drbd_tl_epoch, w);
 	struct drbd_conf *mdev = w->mdev;
-	struct p_barrier *p = mdev->tconn->data.sbuf;
-	int err = 0;
+	struct p_barrier *p;
 
 	/* really avoid racing with tl_clear.  w.cb may have been referenced
 	 * just before it was reassigned and re-queued, so double check that.
@@ -1210,26 +1210,28 @@ int w_send_barrier(struct drbd_work *w, int cancel)
 	if (cancel)
 		return 0;
 
-	err = drbd_get_data_sock(mdev->tconn);
-	if (err)
-		return err;
+	sock = &mdev->tconn->data;
+	p = drbd_prepare_command(mdev, sock);
+	if (!p)
+		return -EIO;
 	p->barrier = b->br_number;
 	/* inc_ap_pending was done where this was queued.
 	 * dec_ap_pending will be done in got_BarrierAck
 	 * or (on connection loss) in w_clear_epoch.  */
-	err = _drbd_send_cmd(mdev, &mdev->tconn->data, P_BARRIER,
-			     &p->head, sizeof(*p), 0);
-	drbd_put_data_sock(mdev->tconn);
-
-	return err;
+	return drbd_send_command(mdev, sock, P_BARRIER, sizeof(*p), NULL, 0);
 }
 
 int w_send_write_hint(struct drbd_work *w, int cancel)
 {
 	struct drbd_conf *mdev = w->mdev;
+	struct drbd_socket *sock;
+
 	if (cancel)
 		return 0;
-	return drbd_send_short_cmd(mdev, P_UNPLUG_REMOTE);
+	sock = &mdev->tconn->data;
+	if (!drbd_prepare_command(mdev, sock))
+		return -EIO;
+	return drbd_send_command(mdev, sock, P_UNPLUG_REMOTE, sizeof(struct p_header), NULL, 0);
 }
 
 int w_send_out_of_sync(struct drbd_work *w, int cancel)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 05/10] drbd: Remove now-unused int_dig_out buffer
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (3 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 04/10] drbd: Replace and remove old primitives Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 14:31 ` [PATCH 06/10] drbd: Remove some fixed header size assumptions Philipp Reisner
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h  |    1 -
 drivers/block/drbd/drbd_main.c |    1 -
 drivers/block/drbd/drbd_nl.c   |    9 ---------
 3 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e5dc772..c58b327 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -893,7 +893,6 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
 	struct crypto_hash *csums_tfm;
 	struct crypto_hash *verify_tfm;
-	void *int_dig_out;
 	void *int_dig_in;
 	void *int_dig_vv;
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 4aec4af..9e94ead 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2380,7 +2380,6 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
 	drbd_free_socket(&tconn->meta);
 	drbd_free_socket(&tconn->data);
 	kfree(tconn->name);
-	kfree(tconn->int_dig_out);
 	kfree(tconn->int_dig_in);
 	kfree(tconn->int_dig_vv);
 	kfree(tconn);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 02d4224..4b60673 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1835,7 +1835,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 	struct crypto_hash *tfm = NULL;
 	struct crypto_hash *integrity_w_tfm = NULL;
 	struct crypto_hash *integrity_r_tfm = NULL;
-	void *int_dig_out = NULL;
 	void *int_dig_in = NULL;
 	void *int_dig_vv = NULL;
 	struct drbd_tconn *oconn;
@@ -2009,11 +2008,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 	/* allocation not in the IO path, cqueue thread context */
 	if (integrity_w_tfm) {
 		i = crypto_hash_digestsize(integrity_w_tfm);
-		int_dig_out = kmalloc(i, GFP_KERNEL);
-		if (!int_dig_out) {
-			retcode = ERR_NOMEM;
-			goto fail;
-		}
 		int_dig_in = kmalloc(i, GFP_KERNEL);
 		if (!int_dig_in) {
 			retcode = ERR_NOMEM;
@@ -2044,10 +2038,8 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 	crypto_free_hash(tconn->integrity_r_tfm);
 	tconn->integrity_r_tfm = integrity_r_tfm;
 
-	kfree(tconn->int_dig_out);
 	kfree(tconn->int_dig_in);
 	kfree(tconn->int_dig_vv);
-	tconn->int_dig_out=int_dig_out;
 	tconn->int_dig_in=int_dig_in;
 	tconn->int_dig_vv=int_dig_vv;
 	retcode = _conn_request_state(tconn, NS(conn, C_UNCONNECTED), CS_VERBOSE);
@@ -2063,7 +2055,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 
 fail:
-	kfree(int_dig_out);
 	kfree(int_dig_in);
 	kfree(int_dig_vv);
 	crypto_free_hash(tfm);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/10] drbd: Remove some fixed header size assumptions
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (4 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 05/10] drbd: Remove now-unused int_dig_out buffer Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 14:31 ` [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*) Philipp Reisner
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   15 +++------------
 drivers/block/drbd/drbd_main.c     |   25 +++++++++++++++----------
 drivers/block/drbd/drbd_receiver.c |   29 +++++++++++++++++------------
 3 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c58b327..d8e63c4 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -543,19 +543,10 @@ struct p_delay_probe93 {
 	u32     offset;  /* usecs the probe got sent after the reference time point */
 } __packed;
 
-/* one bitmap packet, including the p_header,
- * should fit within one _architecture independend_ page.
- * so we need to use the fixed size 4KiB page size
- * most architectures have used for a long time.
+/*
+ * Bitmap packets need to fit within a single page on the sender and receiver,
+ * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger).
  */
-#define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header))
-#define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long))
-#define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm))
-#if (PAGE_SIZE < 4096)
-/* drbd_send_bitmap / receive_bitmap would break horribly */
-#error "PAGE_SIZE too small"
-#endif
-
 #define DRBD_SOCKET_BUFFER_SIZE 4096
 
 /**********************************************************************/
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9e94ead..ee45370 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1082,8 +1082,9 @@ static void dcbp_set_pad_bits(struct p_compressed_bm *p, int n)
 }
 
 int fill_bitmap_rle_bits(struct drbd_conf *mdev,
-	struct p_compressed_bm *p,
-	struct bm_xfer_ctx *c)
+			 struct p_compressed_bm *p,
+			 unsigned int size,
+			 struct bm_xfer_ctx *c)
 {
 	struct bitstream bs;
 	unsigned long plain_bits;
@@ -1102,8 +1103,8 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
 		return 0; /* nothing to do. */
 
 	/* use at most thus many bytes */
-	bitstream_init(&bs, p->code, BM_PACKET_VLI_BYTES_MAX, 0);
-	memset(p->code, 0, BM_PACKET_VLI_BYTES_MAX);
+	bitstream_init(&bs, p->code, size, 0);
+	memset(p->code, 0, size);
 	/* plain bits covered in this code string */
 	plain_bits = 0;
 
@@ -1185,11 +1186,11 @@ static int
 send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 {
 	struct drbd_socket *sock = &mdev->tconn->data;
+	unsigned int header_size = drbd_header_size(mdev->tconn);
 	struct p_compressed_bm *p = sock->sbuf;
-	unsigned long num_words;
 	int len, err;
 
-	len = fill_bitmap_rle_bits(mdev, p, c);
+	len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c);
 	if (len < 0)
 		return -EIO;
 
@@ -1206,9 +1207,14 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 	} else {
 		/* was not compressible.
 		 * send a buffer full of plain text bits instead. */
+		unsigned int data_size;
+		unsigned long num_words;
 		struct p_header *h = sock->sbuf;
-		num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
-		len = num_words * sizeof(long);
+
+		data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
+		num_words = min_t(size_t, data_size / sizeof(unsigned long),
+				  c->bm_words - c->word_offset);
+		len = num_words * sizeof(unsigned long);
 		if (len)
 			drbd_bm_get_lel(mdev, c->word_offset, num_words,
 					(unsigned long *)h->payload);
@@ -1218,7 +1224,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 		c->bit_offset = c->word_offset * BITS_PER_LONG;
 
 		c->packets[1]++;
-		c->bytes[1] += sizeof(struct p_header80) + len;
+		c->bytes[1] += header_size + len;
 
 		if (c->bit_offset > c->bm_bits)
 			c->bit_offset = c->bm_bits;
@@ -2526,7 +2532,6 @@ int __init drbd_init(void)
 {
 	int err;
 
-	BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95));
 	BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);
 
 	if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1270af3..d0d1924 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3663,16 +3663,19 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
  * code upon failure.
  */
 static int
-receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
+receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
 		     struct p_header *h, struct bm_xfer_ctx *c)
 {
 	unsigned long *buffer = (unsigned long *)h->payload;
-	unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
-	unsigned want = num_words * sizeof(long);
+	unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
+				 drbd_header_size(mdev->tconn);
+	unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long),
+				       c->bm_words - c->word_offset);
+	unsigned int want = num_words * sizeof(unsigned long);
 	int err;
 
-	if (want != data_size) {
-		dev_err(DEV, "%s:want (%u) != data_size (%u)\n", __func__, want, data_size);
+	if (want != size) {
+		dev_err(DEV, "%s:want (%u) != size (%u)\n", __func__, want, size);
 		return -EIO;
 	}
 	if (want == 0)
@@ -3799,11 +3802,13 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
 		const char *direction, struct bm_xfer_ctx *c)
 {
 	/* what would it take to transfer it "plaintext" */
-	unsigned plain = sizeof(struct p_header) *
-		((c->bm_words+BM_PACKET_WORDS-1)/BM_PACKET_WORDS+1)
-		+ c->bm_words * sizeof(long);
-	unsigned total = c->bytes[0] + c->bytes[1];
-	unsigned r;
+	unsigned int header_size = drbd_header_size(mdev->tconn);
+	unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
+	unsigned int plain =
+		header_size * (DIV_ROUND_UP(c->bm_words, data_size) + 1) +
+		c->bm_words * sizeof(unsigned long);
+	unsigned int total = c->bytes[0] + c->bytes[1];
+	unsigned int r;
 
 	/* total can not be zero. but just in case: */
 	if (total == 0)
@@ -3865,7 +3870,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
 			 * and the feature is enabled! */
 			struct p_compressed_bm *p;
 
-			if (pi->size > BM_PACKET_PAYLOAD_BYTES) {
+			if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) {
 				dev_err(DEV, "ReportCBitmap packet too large\n");
 				err = -EIO;
 				goto out;
@@ -3888,7 +3893,7 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
 		}
 
 		c.packets[pi->cmd == P_BITMAP]++;
-		c.bytes[pi->cmd == P_BITMAP] += sizeof(struct p_header) + pi->size;
+		c.bytes[pi->cmd == P_BITMAP] += drbd_header_size(tconn) + pi->size;
 
 		if (err <= 0) {
 			if (err < 0)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*)
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (5 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 06/10] drbd: Remove some fixed header size assumptions Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 17:38   ` Kyle Moffett
  2011-09-23 14:31 ` [PATCH 08/10] drbd: Introduce protocol version 100 headers Philipp Reisner
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   45 ----------
 drivers/block/drbd/drbd_main.c     |   44 +++++-----
 drivers/block/drbd/drbd_receiver.c |  171 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_worker.c   |    2 +-
 4 files changed, 108 insertions(+), 154 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d8e63c4..9868518 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -307,32 +307,8 @@ struct p_header95 {
 	u32	  vol_n_len;	/* big endian: high byte = volume; remaining 24 bit = length */
 } __packed;
 
-struct p_header {
-	union {
-		struct p_header80 h80;
-		struct p_header95 h95;
-	};
-	u8	  payload[0];
-};
-
 extern unsigned int drbd_header_size(struct drbd_tconn *tconn);
 
-/*
- * short commands, packets without payload, plain p_header:
- *   P_PING
- *   P_PING_ACK
- *   P_BECOME_SYNC_TARGET
- *   P_BECOME_SYNC_SOURCE
- *   P_UNPLUG_REMOTE
- */
-
-/*
- * commands with out-of-struct payload:
- *   P_BITMAP    (no additional fields)
- *   P_DATA, P_DATA_REPLY (see p_data)
- *   P_COMPRESSED_BITMAP (see receive_compressed_bitmap)
- */
-
 /* these defines must not be changed without changing the protocol version */
 #define DP_HARDBARRIER	      1 /* depricated */
 #define DP_RW_SYNC	      2 /* equals REQ_SYNC    */
@@ -343,7 +319,6 @@ extern unsigned int drbd_header_size(struct drbd_tconn *tconn);
 #define DP_DISCARD           64 /* equals REQ_DISCARD */
 
 struct p_data {
-	struct p_header head;
 	u64	    sector;    /* 64 bits sector number */
 	u64	    block_id;  /* to identify the request in protocol B&C */
 	u32	    seq_num;
@@ -359,7 +334,6 @@ struct p_data {
  *   P_DATA_REQUEST, P_RS_DATA_REQUEST
  */
 struct p_block_ack {
-	struct p_header head;
 	u64	    sector;
 	u64	    block_id;
 	u32	    blksize;
@@ -367,7 +341,6 @@ struct p_block_ack {
 } __packed;
 
 struct p_block_req {
-	struct p_header head;
 	u64 sector;
 	u64 block_id;
 	u32 blksize;
@@ -384,7 +357,6 @@ struct p_block_req {
  */
 
 struct p_connection_features {
-	struct p_header head;   /* Note: vnr will be ignored */
 	u32 protocol_min;
 	u32 feature_flags;
 	u32 protocol_max;
@@ -396,22 +368,18 @@ struct p_connection_features {
 	u32 _pad;
 	u64 reserverd[7];
 } __packed;
-/* 80 bytes, FIXED for the next century */
 
 struct p_barrier {
-	struct p_header head;
 	u32 barrier;	/* barrier number _handle_ only */
 	u32 pad;	/* to multiple of 8 Byte */
 } __packed;
 
 struct p_barrier_ack {
-	struct p_header head;
 	u32 barrier;
 	u32 set_size;
 } __packed;
 
 struct p_rs_param {
-	struct p_header head;
 	u32 rate;
 
 	      /* Since protocol version 88 and higher. */
@@ -419,7 +387,6 @@ struct p_rs_param {
 } __packed;
 
 struct p_rs_param_89 {
-	struct p_header head;
 	u32 rate;
         /* protocol version 89: */
 	char verify_alg[SHARED_SECRET_MAX];
@@ -427,7 +394,6 @@ struct p_rs_param_89 {
 } __packed;
 
 struct p_rs_param_95 {
-	struct p_header head;
 	u32 rate;
 	char verify_alg[SHARED_SECRET_MAX];
 	char csums_alg[SHARED_SECRET_MAX];
@@ -443,7 +409,6 @@ enum drbd_conn_flags {
 };
 
 struct p_protocol {
-	struct p_header head;
 	u32 protocol;
 	u32 after_sb_0p;
 	u32 after_sb_1p;
@@ -457,17 +422,14 @@ struct p_protocol {
 } __packed;
 
 struct p_uuids {
-	struct p_header head;
 	u64 uuid[UI_EXTENDED_SIZE];
 } __packed;
 
 struct p_rs_uuid {
-	struct p_header head;
 	u64	    uuid;
 } __packed;
 
 struct p_sizes {
-	struct p_header head;
 	u64	    d_size;  /* size of disk */
 	u64	    u_size;  /* user requested size */
 	u64	    c_size;  /* current exported size */
@@ -477,18 +439,15 @@ struct p_sizes {
 } __packed;
 
 struct p_state {
-	struct p_header head;
 	u32	    state;
 } __packed;
 
 struct p_req_state {
-	struct p_header head;
 	u32	    mask;
 	u32	    val;
 } __packed;
 
 struct p_req_state_reply {
-	struct p_header head;
 	u32	    retcode;
 } __packed;
 
@@ -503,14 +462,12 @@ struct p_drbd06_param {
 } __packed;
 
 struct p_discard {
-	struct p_header head;
 	u64	    block_id;
 	u32	    seq_num;
 	u32	    pad;
 } __packed;
 
 struct p_block_desc {
-	struct p_header head;
 	u64 sector;
 	u32 blksize;
 	u32 pad;	/* to multiple of 8 Byte */
@@ -526,7 +483,6 @@ enum drbd_bitmap_code {
 };
 
 struct p_compressed_bm {
-	struct p_header head;
 	/* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code
 	 * (encoding & 0x80): polarity (set/unset) of first runlength
 	 * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits
@@ -538,7 +494,6 @@ struct p_compressed_bm {
 } __packed;
 
 struct p_delay_probe93 {
-	struct p_header head;
 	u32     seq_num; /* sequence number to match the two probe packets */
 	u32     offset;  /* usecs the probe got sent after the reference time point */
 } __packed;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ee45370..34cdb97 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -703,27 +703,29 @@ unsigned int drbd_header_size(struct drbd_tconn *tconn)
 	return sizeof(struct p_header80);
 }
 
-static void prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size)
+static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size)
 {
 	h->magic   = cpu_to_be32(DRBD_MAGIC);
 	h->command = cpu_to_be16(cmd);
 	h->length  = cpu_to_be16(size);
+	return sizeof(struct p_header80);
 }
 
-static void prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size, int vnr)
+static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size, int vnr)
 {
 	h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 	h->command = cpu_to_be16(cmd);
 	h->vol_n_len = cpu_to_be32(vnr << 24 | size);
+	return sizeof(struct p_header95);
 }
 
-static void prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h,
-			   enum drbd_packet cmd, int size)
+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)
-		prepare_header95(&h->h95, cmd, size, vnr);
+		return prepare_header95(buffer, cmd, size, vnr);
 	else
-		prepare_header80(&h->h80, cmd, size);
+		return prepare_header80(buffer, cmd, size);
 }
 
 void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
@@ -733,7 +735,7 @@ void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
 		mutex_unlock(&sock->mutex);
 		return NULL;
 	}
-	return sock->sbuf;
+	return sock->sbuf + drbd_header_size(tconn);
 }
 
 void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock)
@@ -758,8 +760,8 @@ static int __send_command(struct drbd_tconn *tconn, int vnr,
 	 */
 	msg_flags = data ? MSG_MORE : 0;
 
-	prepare_header(tconn, vnr, sock->sbuf, cmd,
-		       header_size - sizeof(struct p_header) + size);
+	header_size += prepare_header(tconn, vnr, sock->sbuf, cmd,
+				      header_size + size);
 	err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
 			    msg_flags);
 	if (data && !err)
@@ -797,7 +799,7 @@ int drbd_send_ping(struct drbd_tconn *tconn)
 	sock = &tconn->meta;
 	if (!conn_prepare_command(tconn, sock))
 		return -EIO;
-	return conn_send_command(tconn, sock, P_PING, sizeof(struct p_header), NULL, 0);
+	return conn_send_command(tconn, sock, P_PING, 0, NULL, 0);
 }
 
 int drbd_send_ping_ack(struct drbd_tconn *tconn)
@@ -807,7 +809,7 @@ int drbd_send_ping_ack(struct drbd_tconn *tconn)
 	sock = &tconn->meta;
 	if (!conn_prepare_command(tconn, sock))
 		return -EIO;
-	return conn_send_command(tconn, sock, P_PING_ACK, sizeof(struct p_header), NULL, 0);
+	return conn_send_command(tconn, sock, P_PING_ACK, 0, NULL, 0);
 }
 
 int drbd_send_sync_param(struct drbd_conf *mdev)
@@ -1187,10 +1189,10 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 {
 	struct drbd_socket *sock = &mdev->tconn->data;
 	unsigned int header_size = drbd_header_size(mdev->tconn);
-	struct p_compressed_bm *p = sock->sbuf;
+	struct p_compressed_bm *p = sock->sbuf + header_size;
 	int len, err;
 
-	len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c);
+	len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - header_size, c);
 	if (len < 0)
 		return -EIO;
 
@@ -1200,7 +1202,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 				     P_COMPRESSED_BITMAP, sizeof(*p) + len,
 				     NULL, 0);
 		c->packets[0]++;
-		c->bytes[0] += sizeof(*p) + len;
+		c->bytes[0] += header_size + sizeof(*p) + len;
 
 		if (c->bit_offset >= c->bm_bits)
 			len = 0; /* DONE */
@@ -1209,17 +1211,15 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c)
 		 * send a buffer full of plain text bits instead. */
 		unsigned int data_size;
 		unsigned long num_words;
-		struct p_header *h = sock->sbuf;
+		unsigned long *p = sock->sbuf + header_size;
 
 		data_size = DRBD_SOCKET_BUFFER_SIZE - header_size;
-		num_words = min_t(size_t, data_size / sizeof(unsigned long),
+		num_words = min_t(size_t, data_size / sizeof(*p),
 				  c->bm_words - c->word_offset);
-		len = num_words * sizeof(unsigned long);
+		len = num_words * sizeof(*p);
 		if (len)
-			drbd_bm_get_lel(mdev, c->word_offset, num_words,
-					(unsigned long *)h->payload);
-		err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP,
-				     sizeof(*h) + len, NULL, 0);
+			drbd_bm_get_lel(mdev, c->word_offset, num_words, p);
+		err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP, len, NULL, 0);
 		c->word_offset += num_words;
 		c->bit_offset = c->word_offset * BITS_PER_LONG;
 
@@ -2532,8 +2532,6 @@ int __init drbd_init(void)
 {
 	int err;
 
-	BUILD_BUG_ON(sizeof(struct p_connection_features) != 80);
-
 	if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
 		printk(KERN_ERR
 		       "drbd: invalid minor_count (%d)\n", minor_count);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d0d1924..0b0f453 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -52,6 +52,7 @@ struct packet_info {
 	enum drbd_packet cmd;
 	unsigned int size;
 	unsigned int vnr;
+	void *data;
 };
 
 enum finish_epoch {
@@ -729,14 +730,14 @@ out:
 	return s_estab;
 }
 
-static int decode_header(struct drbd_tconn *, struct p_header *, struct packet_info *);
+static int decode_header(struct drbd_tconn *, void *, struct packet_info *);
 
 static int send_first_packet(struct drbd_tconn *tconn, struct drbd_socket *sock,
 			     enum drbd_packet cmd)
 {
 	if (!conn_prepare_command(tconn, sock))
 		return -EIO;
-	return conn_send_command(tconn, sock, cmd, sizeof(struct p_header), NULL, 0);
+	return conn_send_command(tconn, sock, cmd, 0, NULL, 0);
 }
 
 static int receive_first_packet(struct drbd_tconn *tconn, struct socket *sock)
@@ -978,39 +979,45 @@ out_release_sockets:
 	return -1;
 }
 
-static int decode_header(struct drbd_tconn *tconn, struct p_header *h, struct packet_info *pi)
+static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_info *pi)
 {
-	u32 vol_n_len;
+	unsigned int header_size = drbd_header_size(tconn);
 
-	if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
-		pi->cmd = be16_to_cpu(h->h80.command);
-		pi->size = be16_to_cpu(h->h80.length);
-		pi->vnr = 0;
-	} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
-		pi->cmd = be16_to_cpu(h->h95.command);
-		vol_n_len = be32_to_cpu(h->h95.vol_n_len);
+	if (header_size == sizeof(struct p_header95) &&
+	    *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) {
+		struct p_header95 *h = header;
+		u32 vol_n_len;
+
+		pi->cmd = be16_to_cpu(h->command);
+		vol_n_len = be32_to_cpu(h->vol_n_len);
 		pi->size = vol_n_len & 0x00ffffff;
 		pi->vnr  = vol_n_len >> 24;
+	} else if (header_size == sizeof(struct p_header80) &&
+		   *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) {
+		struct p_header80 *h = header;
+		pi->cmd = be16_to_cpu(h->command);
+		pi->size = be16_to_cpu(h->length);
+		pi->vnr = 0;
 	} else {
-		conn_err(tconn, "magic?? on data m: 0x%08x c: %d l: %d\n",
-		    be32_to_cpu(h->h80.magic),
-		    be16_to_cpu(h->h80.command),
-		    be16_to_cpu(h->h80.length));
+		conn_err(tconn, "Wrong magic value 0x%08x in protocol version %d\n",
+			 be32_to_cpu(*(__be32 *)header),
+			 tconn->agreed_pro_version);
 		return -EINVAL;
 	}
+	pi->data = header + header_size;
 	return 0;
 }
 
 static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	struct p_header *h = tconn->data.rbuf;
+	void *buffer = tconn->data.rbuf;
 	int err;
 
-	err = drbd_recv_all_warn(tconn, h, drbd_header_size(tconn));
+	err = drbd_recv_all_warn(tconn, buffer, drbd_header_size(tconn));
 	if (err)
 		return err;
 
-	err = decode_header(tconn, h, pi);
+	err = decode_header(tconn, buffer, pi);
 	tconn->last_received = jiffies;
 
 	return err;
@@ -1245,7 +1252,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
 	int rv;
-	struct p_barrier *p = tconn->data.rbuf;
+	struct p_barrier *p = pi->data;
 	struct drbd_epoch *epoch;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
@@ -1563,7 +1570,7 @@ static int receive_DataReply(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct drbd_request *req;
 	sector_t sector;
 	int err;
-	struct p_data *p = tconn->data.rbuf;
+	struct p_data *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -1595,7 +1602,7 @@ static int receive_RSDataReply(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct drbd_conf *mdev;
 	sector_t sector;
 	int err;
-	struct p_data *p = tconn->data.rbuf;
+	struct p_data *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -1988,7 +1995,7 @@ static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct drbd_conf *mdev;
 	sector_t sector;
 	struct drbd_peer_request *peer_req;
-	struct p_data *p = tconn->data.rbuf;
+	struct p_data *p = pi->data;
 	u32 peer_seq = be32_to_cpu(p->seq_num);
 	int rw = WRITE;
 	u32 dp_flags;
@@ -2176,7 +2183,7 @@ static int receive_DataRequest(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct digest_info *di = NULL;
 	int size, verb;
 	unsigned int fault_type;
-	struct p_block_req *p =	tconn->data.rbuf;
+	struct p_block_req *p =	pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -2896,7 +2903,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
 
 static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	struct p_protocol *p = tconn->data.rbuf;
+	struct p_protocol *p = pi->data;
 	int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
 	int p_want_lose, p_two_primaries, cf;
 	char p_integrity_alg[SHARED_SECRET_MAX] = "";
@@ -3036,7 +3043,7 @@ static int config_unknown_volume(struct drbd_tconn *tconn, struct packet_info *p
 static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_rs_param_95 *p = tconn->data.rbuf;
+	struct p_rs_param_95 *p;
 	unsigned int header_size, data_size, exp_max_sz;
 	struct crypto_hash *verify_tfm = NULL;
 	struct crypto_hash *csums_tfm = NULL;
@@ -3062,22 +3069,23 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi)
 	}
 
 	if (apv <= 88) {
-		header_size = sizeof(struct p_rs_param) - sizeof(struct p_header);
+		header_size = sizeof(struct p_rs_param);
 		data_size = pi->size - header_size;
 	} else if (apv <= 94) {
-		header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header);
+		header_size = sizeof(struct p_rs_param_89);
 		data_size = pi->size - header_size;
 		D_ASSERT(data_size == 0);
 	} else {
-		header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header);
+		header_size = sizeof(struct p_rs_param_95);
 		data_size = pi->size - header_size;
 		D_ASSERT(data_size == 0);
 	}
 
 	/* initialize verify_alg and csums_alg */
+	p = pi->data;
 	memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
 
-	err = drbd_recv_all(mdev->tconn, &p->head.payload, header_size);
+	err = drbd_recv_all(mdev->tconn, p, header_size);
 	if (err)
 		return err;
 
@@ -3212,7 +3220,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
 static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_sizes *p = tconn->data.rbuf;
+	struct p_sizes *p = pi->data;
 	enum determine_dev_size dd = unchanged;
 	sector_t p_size, p_usize, my_usize;
 	int ldsc = 0; /* local disk size changed */
@@ -3314,7 +3322,7 @@ static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi)
 static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_uuids *p = tconn->data.rbuf;
+	struct p_uuids *p = pi->data;
 	u64 *p_uuid;
 	int i, updated_uuids = 0;
 
@@ -3414,7 +3422,7 @@ static union drbd_state convert_state(union drbd_state ps)
 static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_req_state *p = tconn->data.rbuf;
+	struct p_req_state *p = pi->data;
 	union drbd_state mask, val;
 	enum drbd_state_rv rv;
 
@@ -3444,7 +3452,7 @@ static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi)
 
 static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	struct p_req_state *p = tconn->data.rbuf;
+	struct p_req_state *p = pi->data;
 	union drbd_state mask, val;
 	enum drbd_state_rv rv;
 
@@ -3469,7 +3477,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *
 static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_state *p = tconn->data.rbuf;
+	struct p_state *p = pi->data;
 	union drbd_state os, ns, peer_state;
 	enum drbd_disk_state real_peer_disk;
 	enum chg_state_flags cs_flags;
@@ -3626,7 +3634,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
 static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_rs_uuid *p = tconn->data.rbuf;
+	struct p_rs_uuid *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -3664,14 +3672,13 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi)
  */
 static int
 receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
-		     struct p_header *h, struct bm_xfer_ctx *c)
+		     unsigned long *p, struct bm_xfer_ctx *c)
 {
-	unsigned long *buffer = (unsigned long *)h->payload;
 	unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE -
 				 drbd_header_size(mdev->tconn);
-	unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long),
+	unsigned int num_words = min_t(size_t, data_size / sizeof(*p),
 				       c->bm_words - c->word_offset);
-	unsigned int want = num_words * sizeof(unsigned long);
+	unsigned int want = num_words * sizeof(*p);
 	int err;
 
 	if (want != size) {
@@ -3680,11 +3687,11 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size,
 	}
 	if (want == 0)
 		return 0;
-	err = drbd_recv_all(mdev->tconn, buffer, want);
+	err = drbd_recv_all(mdev->tconn, p, want);
 	if (err)
 		return err;
 
-	drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer);
+	drbd_bm_merge_lel(mdev, c->word_offset, num_words, p);
 
 	c->word_offset += num_words;
 	c->bit_offset = c->word_offset * BITS_PER_LONG;
@@ -3847,7 +3854,6 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct drbd_conf *mdev;
 	struct bm_xfer_ctx c;
 	int err;
-	struct p_header *h = tconn->data.rbuf;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -3863,28 +3869,26 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi)
 	};
 
 	for(;;) {
-		if (pi->cmd == P_BITMAP) {
-			err = receive_bitmap_plain(mdev, pi->size, h, &c);
-		} else if (pi->cmd == P_COMPRESSED_BITMAP) {
+		if (pi->cmd == P_BITMAP)
+			err = receive_bitmap_plain(mdev, pi->size, pi->data, &c);
+		else if (pi->cmd == P_COMPRESSED_BITMAP) {
 			/* MAYBE: sanity check that we speak proto >= 90,
 			 * and the feature is enabled! */
-			struct p_compressed_bm *p;
+			struct p_compressed_bm *p = pi->data;
 
 			if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) {
 				dev_err(DEV, "ReportCBitmap packet too large\n");
 				err = -EIO;
 				goto out;
 			}
-
-			p = mdev->tconn->data.rbuf;
-			err = drbd_recv_all(mdev->tconn, p->head.payload, pi->size);
-			if (err)
-			       goto out;
-			if (pi->size <= (sizeof(*p) - sizeof(p->head))) {
+			if (pi->size <= sizeof(*p)) {
 				dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size);
 				err = -EIO;
 				goto out;
 			}
+			err = drbd_recv_all(mdev->tconn, p, pi->size);
+			if (err)
+			       goto out;
 			err = decode_bitmap_c(mdev, p, &c, pi->size);
 		} else {
 			dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
@@ -3951,7 +3955,7 @@ static int receive_UnplugRemote(struct drbd_tconn *tconn, struct packet_info *pi
 static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_desc *p = tconn->data.rbuf;
+	struct p_block_desc *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -3983,13 +3987,13 @@ static struct data_cmd drbd_cmd_handler[] = {
 	[P_DATA_REPLY]	    = { 1, sizeof(struct p_data), receive_DataReply },
 	[P_RS_DATA_REPLY]   = { 1, sizeof(struct p_data), receive_RSDataReply } ,
 	[P_BARRIER]	    = { 0, sizeof(struct p_barrier), receive_Barrier } ,
-	[P_BITMAP]	    = { 1, sizeof(struct p_header), receive_bitmap } ,
-	[P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
-	[P_UNPLUG_REMOTE]   = { 0, sizeof(struct p_header), receive_UnplugRemote },
+	[P_BITMAP]	    = { 1, 0, receive_bitmap } ,
+	[P_COMPRESSED_BITMAP] = { 1, 0, receive_bitmap } ,
+	[P_UNPLUG_REMOTE]   = { 0, 0, receive_UnplugRemote },
 	[P_DATA_REQUEST]    = { 0, sizeof(struct p_block_req), receive_DataRequest },
 	[P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
-	[P_SYNC_PARAM]	    = { 1, sizeof(struct p_header), receive_SyncParam },
-	[P_SYNC_PARAM89]    = { 1, sizeof(struct p_header), receive_SyncParam },
+	[P_SYNC_PARAM]	    = { 1, 0, receive_SyncParam },
+	[P_SYNC_PARAM89]    = { 1, 0, receive_SyncParam },
 	[P_PROTOCOL]        = { 1, sizeof(struct p_protocol), receive_protocol },
 	[P_UUIDS]	    = { 0, sizeof(struct p_uuids), receive_uuids },
 	[P_SIZES]	    = { 0, sizeof(struct p_sizes), receive_sizes },
@@ -4006,7 +4010,6 @@ static struct data_cmd drbd_cmd_handler[] = {
 
 static void drbdd(struct drbd_tconn *tconn)
 {
-	struct p_header *header = tconn->data.rbuf;
 	struct packet_info pi;
 	size_t shs; /* sub header size */
 	int err;
@@ -4024,14 +4027,14 @@ static void drbdd(struct drbd_tconn *tconn)
 			goto err_out;
 		}
 
-		shs = cmd->pkt_size - sizeof(struct p_header);
-		if (pi.size - shs > 0 && !cmd->expect_payload) {
+		shs = cmd->pkt_size;
+		if (pi.size > shs && !cmd->expect_payload) {
 			conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
 			goto err_out;
 		}
 
 		if (shs) {
-			err = drbd_recv_all_warn(tconn, &header->payload, shs);
+			err = drbd_recv_all_warn(tconn, pi.data, shs);
 			if (err)
 				goto err_out;
 			pi.size -= shs;
@@ -4222,8 +4225,8 @@ static int drbd_send_features(struct drbd_tconn *tconn)
 static int drbd_do_features(struct drbd_tconn *tconn)
 {
 	/* ASSERT current == tconn->receiver ... */
-	struct p_connection_features *p = tconn->data.rbuf;
-	const int expect = sizeof(struct p_connection_features) - sizeof(struct p_header80);
+	struct p_connection_features *p;
+	const int expect = sizeof(struct p_connection_features);
 	struct packet_info pi;
 	int err;
 
@@ -4247,7 +4250,8 @@ static int drbd_do_features(struct drbd_tconn *tconn)
 		return -1;
 	}
 
-	err = drbd_recv_all_warn(tconn, &p->head.payload, expect);
+	p = pi.data;
+	err = drbd_recv_all_warn(tconn, p, expect);
 	if (err)
 		return 0;
 
@@ -4325,8 +4329,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 		rv = 0;
 		goto fail;
 	}
-	rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE,
-				sizeof(struct p_header),
+	rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE, 0,
 				my_challenge, CHALLENGE_LEN);
 	if (!rv)
 		goto fail;
@@ -4385,8 +4388,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 		rv = 0;
 		goto fail;
 	}
-	rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE,
-				sizeof(struct p_header),
+	rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE, 0,
 				response, resp_size);
 	if (!rv)
 		goto fail;
@@ -4485,7 +4487,7 @@ int drbdd_init(struct drbd_thread *thi)
 
 static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	struct p_req_state_reply *p = tconn->meta.rbuf;
+	struct p_req_state_reply *p = pi->data;
 	int retcode = be32_to_cpu(p->retcode);
 
 	if (retcode >= SS_SUCCESS) {
@@ -4503,7 +4505,7 @@ static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_req_state_reply *p = tconn->meta.rbuf;
+	struct p_req_state_reply *p = pi->data;
 	int retcode = be32_to_cpu(p->retcode);
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
@@ -4541,7 +4543,7 @@ static int got_PingAck(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_IsInSync(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 	sector_t sector = be64_to_cpu(p->sector);
 	int blksize = be32_to_cpu(p->blksize);
 
@@ -4591,7 +4593,7 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
 static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 	sector_t sector = be64_to_cpu(p->sector);
 	int blksize = be32_to_cpu(p->blksize);
 	enum drbd_req_event what;
@@ -4641,7 +4643,7 @@ static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 	sector_t sector = be64_to_cpu(p->sector);
 	int size = be32_to_cpu(p->blksize);
 	bool missing_ok = tconn->net_conf->wire_protocol == DRBD_PROT_A ||
@@ -4679,7 +4681,7 @@ static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_NegDReply(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 	sector_t sector = be64_to_cpu(p->sector);
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
@@ -4701,7 +4703,7 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi)
 	struct drbd_conf *mdev;
 	sector_t sector;
 	int size;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -4735,7 +4737,7 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_barrier_ack *p = tconn->meta.rbuf;
+	struct p_barrier_ack *p = pi->data;
 
 	mdev = vnr_to_mdev(tconn, pi->vnr);
 	if (!mdev)
@@ -4756,7 +4758,7 @@ static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi)
 static int got_OVResult(struct drbd_tconn *tconn, struct packet_info *pi)
 {
 	struct drbd_conf *mdev;
-	struct p_block_ack *p = tconn->meta.rbuf;
+	struct p_block_ack *p = pi->data;
 	struct drbd_work *w;
 	sector_t sector;
 	int size;
@@ -4840,8 +4842,8 @@ struct asender_cmd {
 };
 
 static struct asender_cmd asender_tbl[] = {
-	[P_PING]	    = { sizeof(struct p_header), got_Ping },
-	[P_PING_ACK]	    = { sizeof(struct p_header), got_PingAck },
+	[P_PING]	    = { 0, got_Ping },
+	[P_PING_ACK]	    = { 0, got_PingAck },
 	[P_RECV_ACK]	    = { sizeof(struct p_block_ack), got_BlockAck },
 	[P_WRITE_ACK]	    = { sizeof(struct p_block_ack), got_BlockAck },
 	[P_RS_WRITE_ACK]    = { sizeof(struct p_block_ack), got_BlockAck },
@@ -4862,11 +4864,10 @@ static struct asender_cmd asender_tbl[] = {
 int drbd_asender(struct drbd_thread *thi)
 {
 	struct drbd_tconn *tconn = thi->tconn;
-	struct p_header *h = tconn->meta.rbuf;
 	struct asender_cmd *cmd = NULL;
 	struct packet_info pi;
 	int rv;
-	void *buf    = h;
+	void *buf    = tconn->meta.rbuf;
 	int received = 0;
 	unsigned int header_size = drbd_header_size(tconn);
 	int expect   = header_size;
@@ -4944,7 +4945,7 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (decode_header(tconn, h, &pi))
+			if (decode_header(tconn, tconn->meta.rbuf, &pi))
 				goto reconnect;
 			cmd = &asender_tbl[pi.cmd];
 			if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) {
@@ -4952,7 +4953,7 @@ int drbd_asender(struct drbd_thread *thi)
 					pi.cmd, pi.size);
 				goto disconnect;
 			}
-			expect = cmd->pkt_size;
+			expect = header_size + cmd->pkt_size;
 			if (pi.size != expect - header_size) {
 				conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n",
 					pi.cmd, pi.size);
@@ -4975,7 +4976,7 @@ int drbd_asender(struct drbd_thread *thi)
 			if (cmd == &asender_tbl[P_PING_ACK])
 				ping_timeout_active = 0;
 
-			buf	 = h;
+			buf	 = tconn->meta.rbuf;
 			received = 0;
 			expect	 = header_size;
 			cmd	 = NULL;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 6feaa4a..3c7b6d7 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1231,7 +1231,7 @@ int w_send_write_hint(struct drbd_work *w, int cancel)
 	sock = &mdev->tconn->data;
 	if (!drbd_prepare_command(mdev, sock))
 		return -EIO;
-	return drbd_send_command(mdev, sock, P_UNPLUG_REMOTE, sizeof(struct p_header), NULL, 0);
+	return drbd_send_command(mdev, sock, P_UNPLUG_REMOTE, 0, NULL, 0);
 }
 
 int w_send_out_of_sync(struct drbd_work *w, int cancel)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 08/10] drbd: Introduce protocol version 100 headers
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (6 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*) Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 17:42   ` Kyle Moffett
  2011-09-23 14:31 ` [PATCH 09/10] drbd: Remove volume numbers from struct p_header95 Philipp Reisner
  2011-09-23 14:31 ` [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions Philipp Reisner
  9 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    8 ++++++++
 drivers/block/drbd/drbd_main.c     |   31 +++++++++++++++++++++++++------
 drivers/block/drbd/drbd_receiver.c |   14 ++++++++++++--
 include/linux/drbd.h               |    1 +
 4 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9868518..7d679c5 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -307,6 +307,14 @@ struct p_header95 {
 	u32	  vol_n_len;	/* big endian: high byte = volume; remaining 24 bit = length */
 } __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 34cdb97..3310986 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,23 @@ 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)
 		return prepare_header95(buffer, cmd, size, vnr);
 	else
 		return prepare_header80(buffer, cmd, size);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0b0f453..de09cc1 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;
 		u32 vol_n_len;
 
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 60d3088..fe8d6ba 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==" ;) */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 09/10] drbd: Remove volume numbers from struct p_header95
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (7 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 08/10] drbd: Introduce protocol version 100 headers Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 17:28   ` Kyle Moffett
  2011-09-23 14:31 ` [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions Philipp Reisner
  9 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    2 +-
 drivers/block/drbd/drbd_main.c     |    6 +++---
 drivers/block/drbd/drbd_receiver.c |    7 ++-----
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 7d679c5..8f67093 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -304,7 +304,7 @@ struct p_header80 {
 struct p_header95 {
 	u16	  magic;	/* use DRBD_MAGIC_BIG here */
 	u16	  command;
-	u32	  vol_n_len;	/* big endian: high byte = volume; remaining 24 bit = length */
+	u32	  length;
 } __packed;
 
 struct p_header100 {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 3310986..99b467e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -717,11 +717,11 @@ static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd,
 	return sizeof(struct p_header80);
 }
 
-static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size, int vnr)
+static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size)
 {
 	h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 	h->command = cpu_to_be16(cmd);
-	h->vol_n_len = cpu_to_be32(vnr << 24 | size);
+	h->length = cpu_to_be32(size);
 	return sizeof(struct p_header95);
 }
 
@@ -742,7 +742,7 @@ static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr,
 	if (tconn->agreed_pro_version >= 100)
 		return prepare_header100(buffer, cmd, size, vnr);
 	else if (tconn->agreed_pro_version >= 95)
-		return prepare_header95(buffer, cmd, size, vnr);
+		return prepare_header95(buffer, cmd, size);
 	else
 		return prepare_header80(buffer, cmd, size);
 }
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index de09cc1..7539253 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -996,12 +996,9 @@ static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_i
 	} else if (header_size == sizeof(struct p_header95) &&
 		   *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) {
 		struct p_header95 *h = header;
-		u32 vol_n_len;
-
 		pi->cmd = be16_to_cpu(h->command);
-		vol_n_len = be32_to_cpu(h->vol_n_len);
-		pi->size = vol_n_len & 0x00ffffff;
-		pi->vnr  = vol_n_len >> 24;
+		pi->size = be32_to_cpu(h->length);
+		pi->vnr = 0;
 	} else if (header_size == sizeof(struct p_header80) &&
 		   *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) {
 		struct p_header80 *h = header;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions
  2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
                   ` (8 preceding siblings ...)
  2011-09-23 14:31 ` [PATCH 09/10] drbd: Remove volume numbers from struct p_header95 Philipp Reisner
@ 2011-09-23 14:31 ` Philipp Reisner
  2011-09-23 17:24   ` Kyle Moffett
  9 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-23 14:31 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

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>
---
 drivers/block/drbd/drbd_main.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 99b467e..6afcfab 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -741,7 +741,8 @@ static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr,
 {
 	if (tconn->agreed_pro_version >= 100)
 		return prepare_header100(buffer, cmd, size, vnr);
-	else if (tconn->agreed_pro_version >= 95)
+	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);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions
  2011-09-23 14:31 ` [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions Philipp Reisner
@ 2011-09-23 17:24   ` Kyle Moffett
  0 siblings, 0 replies; 23+ messages in thread
From: Kyle Moffett @ 2011-09-23 17:24 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> 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.

If I understand it correctly, this patch fixes a backwards compat bug in
code introduced 2 patches earlier:
  [PATCH 08/10] drbd: Introduce protocol version 100 headers

Therefore this patch (and its commit message) should just be rolled into
that one to prevent the bug in the first place.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 09/10] drbd: Remove volume numbers from struct p_header95
  2011-09-23 14:31 ` [PATCH 09/10] drbd: Remove volume numbers from struct p_header95 Philipp Reisner
@ 2011-09-23 17:28   ` Kyle Moffett
  2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Kyle Moffett @ 2011-09-23 17:28 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

Hi!

On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> From: Andreas Gruenbacher <agruen@linbit.com>
>
> Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> ---
[...snip...]
> diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
> index 3310986..99b467e 100644
> --- a/drivers/block/drbd/drbd_main.c
> +++ b/drivers/block/drbd/drbd_main.c
> @@ -717,11 +717,11 @@ static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd,
>        return sizeof(struct p_header80);
>  }
>
> -static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size, int vnr)
> +static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size)
>  {
>        h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
>        h->command = cpu_to_be16(cmd);
> -       h->vol_n_len = cpu_to_be32(vnr << 24 | size);
> +       h->length = cpu_to_be32(size);
>        return sizeof(struct p_header95);
>  }

This patch needs a commit message indicating why it does not break
compatibility.  If you are guaranteed that the "vnr" passed into
prepare_header95 is always zero, then you should indicate why that is
true.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 04/10] drbd: Replace and remove old primitives
  2011-09-23 14:31 ` [PATCH 04/10] drbd: Replace and remove old primitives Philipp Reisner
@ 2011-09-23 17:33   ` Kyle Moffett
  2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Kyle Moffett @ 2011-09-23 17:33 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

Hi!

On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> From: Andreas Gruenbacher <agruen@linbit.com>
>
> Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> ---
>  drivers/block/drbd/drbd_int.h      |   45 +----
>  drivers/block/drbd/drbd_main.c     |  502 ++++++++++++++++--------------------
>  drivers/block/drbd/drbd_receiver.c |   86 ++++---
>  drivers/block/drbd/drbd_worker.c   |   24 +-
>  4 files changed, 294 insertions(+), 363 deletions(-)

I'm afraid this commit is waaaaay too large and complicated
to have a one-line commit message.

You should either split this up into more pieces or you should
write a detailed log indicated what this is supposed to be doing
and why it is OK.  (Or both).

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*)
  2011-09-23 14:31 ` [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*) Philipp Reisner
@ 2011-09-23 17:38   ` Kyle Moffett
  2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Kyle Moffett @ 2011-09-23 17:38 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

Hi!

On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> From: Andreas Gruenbacher <agruen@linbit.com>
>
> Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> ---
>  drivers/block/drbd/drbd_int.h      |   45 ----------
>  drivers/block/drbd/drbd_main.c     |   44 +++++-----
>  drivers/block/drbd/drbd_receiver.c |  171 ++++++++++++++++++------------------
>  drivers/block/drbd/drbd_worker.c   |    2 +-

This commit is kind of borderline too-big for just a one-line commit message.

It is admittedly very simple (changing the same pointer math in ~50 places),
but it needs a bit more explanation about why it's helpful or necessary.

I *think* it's because the protocol-100 code will use a different-sized header,
but that needs to be actually explained somewhere.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 08/10] drbd: Introduce protocol version 100 headers
  2011-09-23 14:31 ` [PATCH 08/10] drbd: Introduce protocol version 100 headers Philipp Reisner
@ 2011-09-23 17:42   ` Kyle Moffett
  2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Kyle Moffett @ 2011-09-23 17:42 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

Hi!

On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> From: Andreas Gruenbacher <agruen@linbit.com>
>
> Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> ---
>  drivers/block/drbd/drbd_int.h      |    8 ++++++++
>  drivers/block/drbd/drbd_main.c     |   31 +++++++++++++++++++++++++------
>  drivers/block/drbd/drbd_receiver.c |   14 ++++++++++++--
>  include/linux/drbd.h               |    1 +
>  4 files changed, 46 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
> index 9868518..7d679c5 100644
> --- a/drivers/block/drbd/drbd_int.h
> +++ b/drivers/block/drbd/drbd_int.h
> @@ -307,6 +307,14 @@ struct p_header95 {
>        u32       vol_n_len;    /* big endian: high byte = volume; remaining 24 bit = length */
>  } __packed;
>
> +struct p_header100 {
> +       u32       magic;
> +       u16       volume;
> +       u16       command;
> +       u32       length;
> +       u32       pad;
> +} __packed;
> +

This commit also needs additional log message text,
specifically something that indicates what is new and
different between the protocol 95 and protocol 100
headers.  (IE: Why was the change made?)

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 04/10] drbd: Replace and remove old primitives
  2011-09-23 17:33   ` Kyle Moffett
@ 2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-27  9:34 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Jens Axboe, drbd-dev

Am Freitag, 23. September 2011, 19:33:45 schrieb Kyle Moffett:
> Hi!
> 
> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > From: Andreas Gruenbacher <agruen@linbit.com>
> > 
> > Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> > Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> > ---
> >  drivers/block/drbd/drbd_int.h      |   45 +----
> >  drivers/block/drbd/drbd_main.c     |  502
> > ++++++++++++++++-------------------- drivers/block/drbd/drbd_receiver.c
> > |   86 ++++---
> >  drivers/block/drbd/drbd_worker.c   |   24 +-
> >  4 files changed, 294 insertions(+), 363 deletions(-)
> 
> I'm afraid this commit is waaaaay too large and complicated
> to have a one-line commit message.
> 
> You should either split this up into more pieces or you should
> write a detailed log indicated what this is supposed to be doing
> and why it is OK.  (Or both).
> 

I updated the patch to the following commit message:

Author: Andreas Gruenbacher <agruen@linbit.com>
Date:   Mon Mar 28 14:23:08 2011 +0200

    drbd: Replace and remove old primitives
    
    Centralize sock->mutex locking and unlocking in [drbd|conn]_prepare_command()
    and [drbd|conn]_send_comman().
    
    Therefore all *_send_* functions are touched to use these primitives instead
    of drbd_get_data_sock()/drbd_put_data_sock() and former helper functions.
    
    That change makes the *_send_* functions more standardized.
    
    Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
    Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>


The complete, updated set is available at:
git://git.drbd.org/linux-2.6-drbd.git for-jens

Best,
 Phil
-- 
: Dipl-Ing Philipp Reisner
: LINBIT | Your Way to High Availability
: Tel: +43-1-8178292-50, Fax: +43-1-8178292-82
: http://www.linbit.com

DRBD(R) and LINBIT(R) are registered trademarks of LINBIT, Austria.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*)
  2011-09-23 17:38   ` Kyle Moffett
@ 2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-27  9:34 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Jens Axboe, drbd-dev

Am Freitag, 23. September 2011, 19:38:15 schrieb Kyle Moffett:
> Hi!
> 
> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > From: Andreas Gruenbacher <agruen@linbit.com>
> > 
> > Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> > Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> > ---
> >  drivers/block/drbd/drbd_int.h      |   45 ----------
> >  drivers/block/drbd/drbd_main.c     |   44 +++++-----
> >  drivers/block/drbd/drbd_receiver.c |  171
> > ++++++++++++++++++------------------ drivers/block/drbd/drbd_worker.c  
> > |    2 +-
> 
> This commit is kind of borderline too-big for just a one-line commit
> message.
> 
> It is admittedly very simple (changing the same pointer math in ~50
> places), but it needs a bit more explanation about why it's helpful or
> necessary.
> 
> I *think* it's because the protocol-100 code will use a different-sized
> header, but that needs to be actually explained somewhere.
> 

I updated the patch to carry the following commit message:

Author: Andreas Gruenbacher <agruen@linbit.com>
Date:   Wed Mar 30 12:54:42 2011 +0200

    drbd: Remove headers from on-the-wire data structures (struct p_*)
    
    Prepare the introduction of the protocol 100 headers. The actual protocol
    header is removed for the packet declarations. I.e. allow us to use the
    packets with different headers.
    
    Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
    Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>

Best,
 Phil
-- 
: Dipl-Ing Philipp Reisner
: LINBIT | Your Way to High Availability
: Tel: +43-1-8178292-50, Fax: +43-1-8178292-82
: http://www.linbit.com

DRBD(R) and LINBIT(R) are registered trademarks of LINBIT, Austria.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 08/10] drbd: Introduce protocol version 100 headers
  2011-09-23 17:42   ` Kyle Moffett
@ 2011-09-27  9:34     ` Philipp Reisner
  0 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-27  9:34 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Jens Axboe, drbd-dev

Am Freitag, 23. September 2011, 19:42:52 schrieb Kyle Moffett:
> Hi!
> 
> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > From: Andreas Gruenbacher <agruen@linbit.com>
> > 
> > Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> > Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> > ---
> >  drivers/block/drbd/drbd_int.h      |    8 ++++++++
> >  drivers/block/drbd/drbd_main.c     |   31
> > +++++++++++++++++++++++++------ drivers/block/drbd/drbd_receiver.c |  
> > 14 ++++++++++++--
> >  include/linux/drbd.h               |    1 +
> >  4 files changed, 46 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/block/drbd/drbd_int.h
> > b/drivers/block/drbd/drbd_int.h index 9868518..7d679c5 100644
> > --- a/drivers/block/drbd/drbd_int.h
> > +++ b/drivers/block/drbd/drbd_int.h
> > @@ -307,6 +307,14 @@ struct p_header95 {
> >        u32       vol_n_len;    /* big endian: high byte = volume;
> > remaining 24 bit = length */ } __packed;
> > 
> > +struct p_header100 {
> > +       u32       magic;
> > +       u16       volume;
> > +       u16       command;
> > +       u32       length;
> > +       u32       pad;
> > +} __packed;
> > +
> 
> This commit also needs additional log message text,
> specifically something that indicates what is new and
> different between the protocol 95 and protocol 100
> headers.  (IE: Why was the change made?)
> 

I merged patch 10/10 to this one. The updated, and merged
commit message is:

Author: Andreas Gruenbacher <agruen@linbit.com>
Date:   Wed Mar 30 16:00:17 2011 +0200

    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>

Best,
 Phil
-- 
: Dipl-Ing Philipp Reisner
: LINBIT | Your Way to High Availability
: Tel: +43-1-8178292-50, Fax: +43-1-8178292-82
: http://www.linbit.com

DRBD(R) and LINBIT(R) are registered trademarks of LINBIT, Austria.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 09/10] drbd: Remove volume numbers from struct p_header95
  2011-09-23 17:28   ` Kyle Moffett
@ 2011-09-27  9:34     ` Philipp Reisner
  2011-09-28  4:26       ` Kyle Moffett
  0 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-27  9:34 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Jens Axboe, drbd-dev

Am Freitag, 23. September 2011, 19:28:24 schrieb Kyle Moffett:
> Hi!
> 
> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > From: Andreas Gruenbacher <agruen@linbit.com>
> > 
> > Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
> > Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
> > ---
> 
> [...snip...]
> 
> > diff --git a/drivers/block/drbd/drbd_main.c
> > b/drivers/block/drbd/drbd_main.c index 3310986..99b467e 100644
> > --- a/drivers/block/drbd/drbd_main.c
> > +++ b/drivers/block/drbd/drbd_main.c
> > @@ -717,11 +717,11 @@ static unsigned int prepare_header80(struct
> > p_header80 *h, enum drbd_packet cmd, return sizeof(struct p_header80);
> >  }
> > 
> > -static unsigned int prepare_header95(struct p_header95 *h, enum
> > drbd_packet cmd, int size, int vnr) +static unsigned int
> > prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size) {
> >        h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
> >        h->command = cpu_to_be16(cmd);
> > -       h->vol_n_len = cpu_to_be32(vnr << 24 | size);
> > +       h->length = cpu_to_be32(size);
> >        return sizeof(struct p_header95);
> >  }
> 
> This patch needs a commit message indicating why it does not break
> compatibility.  If you are guaranteed that the "vnr" passed into
> prepare_header95 is always zero, then you should indicate why that is
> true.
> 

Here is the commit message for that one. The alternative is to merge
that to patch 'drbd: Use new header layout, and send volume IOs'.
( Which is patch number 236, i.e. outside of this (10th) posting of
  DRBD-8.4 patches. It was posted on August 25.
  See https://lkml.org/lkml/2011/8/25/322 )

Author: Andreas Gruenbacher <agruen@linbit.com>
Date:   Tue Mar 22 13:17:47 2011 +0100

    drbd: Remove volume numbers from struct p_header95
    
    Remove the temporal 8 bit volume number form header 95. All connections
    that support multiple volumes are new using protocol 100 with header 100.
    
    Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
    Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>

Best,
 Phil
-- 
: Dipl-Ing Philipp Reisner
: LINBIT | Your Way to High Availability
: Tel: +43-1-8178292-50, Fax: +43-1-8178292-82
: http://www.linbit.com

DRBD(R) and LINBIT(R) are registered trademarks of LINBIT, Austria.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 09/10] drbd: Remove volume numbers from struct p_header95
  2011-09-27  9:34     ` Philipp Reisner
@ 2011-09-28  4:26       ` Kyle Moffett
  2011-09-28  9:20         ` Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Kyle Moffett @ 2011-09-28  4:26 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

On Tue, Sep 27, 2011 at 05:34, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> Am Freitag, 23. September 2011, 19:28:24 schrieb Kyle Moffett:
>> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner <philipp.reisner@linbit.com> wrote:
>> > diff --git a/drivers/block/drbd/drbd_main.c
>> > b/drivers/block/drbd/drbd_main.c index 3310986..99b467e 100644
>> > --- a/drivers/block/drbd/drbd_main.c
>> > +++ b/drivers/block/drbd/drbd_main.c
>> > @@ -717,11 +717,11 @@ static unsigned int prepare_header80(struct
>> > p_header80 *h, enum drbd_packet cmd, return sizeof(struct p_header80);
>> >  }
>> >
>> > -static unsigned int prepare_header95(struct p_header95 *h, enum
>> > drbd_packet cmd, int size, int vnr) +static unsigned int
>> > prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size) {
>> >        h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
>> >        h->command = cpu_to_be16(cmd);
>> > -       h->vol_n_len = cpu_to_be32(vnr << 24 | size);
>> > +       h->length = cpu_to_be32(size);
>> >        return sizeof(struct p_header95);
>> >  }
>>
>> This patch needs a commit message indicating why it does not break
>> compatibility.  If you are guaranteed that the "vnr" passed into
>> prepare_header95 is always zero, then you should indicate why that is
>> true.
>
> Here is the commit message for that one. The alternative is to merge
> that to patch 'drbd: Use new header layout, and send volume IOs'.
> ( Which is patch number 236, i.e. outside of this (10th) posting of
>  DRBD-8.4 patches. It was posted on August 25.
>  See https://lkml.org/lkml/2011/8/25/322 )
>
> Author: Andreas Gruenbacher <agruen@linbit.com>
> Date:   Tue Mar 22 13:17:47 2011 +0100
>
>    drbd: Remove volume numbers from struct p_header95
>
>    Remove the temporal 8 bit volume number form header 95. All connections
>    that support multiple volumes are new using protocol 100 with header 100.

So my concern is that this effectively ignores an old field in
header95, so an old DRBD trying to talk about multiple volumes to a
new DRBD using header95 is going to get its volume number ignored,
right?

This means that old-DRBD and new-DRBD cannot communicate about
multiple volumes over one connection at all.  That needs to be made an
explicit part of this commit message and the rationale explained in
detail.

In particular, you need to make sure to describe what negotiation
mechanism prevents multiple-volume-header95 messages from being sent
to a version of DRBD including this commit.  If that behavior (IE: a
negotiation change) is part of another commit, then this is small
enough that I would merge it with that other commit, but it still
needs comments about why version interoperability will not break.

It seems to me like DRBD has historically not been terribly strict
with backwards-compatibility to very old versions, but now that it is
in the upstream kernel that is a very serious concern.  With an
out-of-tree module you have a lot more control over exactly which
version you are running, but when it's in-tree you are stuck with
whatever your vendor's kernel version is (for the most part).  Any
time you change or break backwards compatibility there needs to be at
the very *least* a detailed comment indicating why it needs to be
broken and exactly how you avoid additional complications from that.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 09/10] drbd: Remove volume numbers from struct p_header95
  2011-09-28  4:26       ` Kyle Moffett
@ 2011-09-28  9:20         ` Philipp Reisner
  2011-09-28  9:21           ` [PATCH 9/9] drbd: Removed outdated comments and code that envisioned VNRs in header 95 Philipp Reisner
  0 siblings, 1 reply; 23+ messages in thread
From: Philipp Reisner @ 2011-09-28  9:20 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel, Jens Axboe, drbd-dev

Am Mittwoch, 28. September 2011, 06:26:45 schrieb Kyle Moffett:
> On Tue, Sep 27, 2011 at 05:34, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > Am Freitag, 23. September 2011, 19:28:24 schrieb Kyle Moffett:
> >> On Fri, Sep 23, 2011 at 10:31, Philipp Reisner 
<philipp.reisner@linbit.com> wrote:
> >> > diff --git a/drivers/block/drbd/drbd_main.c
> >> > b/drivers/block/drbd/drbd_main.c index 3310986..99b467e 100644
> >> > --- a/drivers/block/drbd/drbd_main.c
> >> > +++ b/drivers/block/drbd/drbd_main.c
> >> > @@ -717,11 +717,11 @@ static unsigned int prepare_header80(struct
> >> > p_header80 *h, enum drbd_packet cmd, return sizeof(struct p_header80);
> >> >  }
> >> > 
> >> > -static unsigned int prepare_header95(struct p_header95 *h, enum
> >> > drbd_packet cmd, int size, int vnr) +static unsigned int
> >> > prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size)
> >> > { h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
> >> >        h->command = cpu_to_be16(cmd);
> >> > -       h->vol_n_len = cpu_to_be32(vnr << 24 | size);
> >> > +       h->length = cpu_to_be32(size);
> >> >        return sizeof(struct p_header95);
> >> >  }
> >> 
> >> This patch needs a commit message indicating why it does not break
> >> compatibility.  If you are guaranteed that the "vnr" passed into
> >> prepare_header95 is always zero, then you should indicate why that is
> >> true.
> > 
> > Here is the commit message for that one. The alternative is to merge
> > that to patch 'drbd: Use new header layout, and send volume IOs'.
> > ( Which is patch number 236, i.e. outside of this (10th) posting of
> >  DRBD-8.4 patches. It was posted on August 25.
> >  See https://lkml.org/lkml/2011/8/25/322 )
> > 
> > Author: Andreas Gruenbacher <agruen@linbit.com>
> > Date:   Tue Mar 22 13:17:47 2011 +0100
> > 
> >    drbd: Remove volume numbers from struct p_header95
> > 
> >    Remove the temporal 8 bit volume number form header 95. All
> > connections that support multiple volumes are new using protocol 100
> > with header 100.
> 
> So my concern is that this effectively ignores an old field in
> header95, so an old DRBD trying to talk about multiple volumes to a
> new DRBD using header95 is going to get its volume number ignored,
> right?
> 
> This means that old-DRBD and new-DRBD cannot communicate about
> multiple volumes over one connection at all.  That needs to be made an
> explicit part of this commit message and the rationale explained in
> detail.
> 
> In particular, you need to make sure to describe what negotiation
> mechanism prevents multiple-volume-header95 messages from being sent
> to a version of DRBD including this commit.  If that behavior (IE: a
> negotiation change) is part of another commit, then this is small
> enough that I would merge it with that other commit, but it still
> needs comments about why version interoperability will not break.
> 
> It seems to me like DRBD has historically not been terribly strict
> with backwards-compatibility to very old versions, but now that it is
> in the upstream kernel that is a very serious concern.  With an
> out-of-tree module you have a lot more control over exactly which
> version you are running, but when it's in-tree you are stuck with
> whatever your vendor's kernel version is (for the most part).  Any
> time you change or break backwards compatibility there needs to be at
> the very *least* a detailed comment indicating why it needs to be
> broken and exactly how you avoid additional complications from that.
> 

Hi,

Well, the last time we broke the on-the-wire compatibility was in January
2007, with the release of drbd-8.0.0. Since then all newer releases can
connect to drbd-8.0.0 and every release in between. (Side node: The 8.0
code was also the code we submitted for inclusion into mainline for the
first time back in 2007)

What happened here in this patch set is, that first (with patch #236)
the volume number gets introduced in the highest byte of the length
(since the bio size only needs 20 bits currently that is valid).
Later on the protocol 100 header gets implemented, and the
volume number field in header 95 is removed again.

So the header 95 with volume numbers is a temporal thing, that happened
during development. It was never in a released version.

Ok, to put an end to this discussion:
I changed patch #236 to never introduce that field into header 95.
As a consequence this patch 'drbd: Remove volume numbers from struct 
p_header95' turns into the removal of outdated comments. See the follow-up
mail.

Best,
 Phil

-- 
: Dipl-Ing Philipp Reisner
: LINBIT | Your Way to High Availability
: Tel: +43-1-8178292-50, Fax: +43-1-8178292-82
: http://www.linbit.com

DRBD(R) and LINBIT(R) are registered trademarks of LINBIT, Austria.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 9/9] drbd: Removed outdated comments and code that envisioned VNRs in header 95
  2011-09-28  9:20         ` Philipp Reisner
@ 2011-09-28  9:21           ` Philipp Reisner
  0 siblings, 0 replies; 23+ messages in thread
From: Philipp Reisner @ 2011-09-28  9:21 UTC (permalink / raw)
  To: Kyle Moffett, linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Since have now header 100, that has space for 16 bit volume numbers,
the high byte of the length in header 95 is no longer reserved for
8 bit volume numbers.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    2 +-
 drivers/block/drbd/drbd_main.c     |    2 +-
 drivers/block/drbd/drbd_receiver.c |    5 ++---
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2fcf370..8f67093 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -304,7 +304,7 @@ struct p_header80 {
 struct p_header95 {
 	u16	  magic;	/* use DRBD_MAGIC_BIG here */
 	u16	  command;
-	u32	  length;	/* Use only 24 bits of that. Ignore the highest 8 bit. */
+	u32	  length;
 } __packed;
 
 struct p_header100 {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 2c75a03..6afcfab 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -721,7 +721,7 @@ static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd,
 {
 	h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 	h->command = cpu_to_be16(cmd);
-	h->length  = cpu_to_be32(size);
+	h->length = cpu_to_be32(size);
 	return sizeof(struct p_header95);
 }
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 80bbc55..7539253 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -996,10 +996,9 @@ static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_i
 	} 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);
-		pi->size = be32_to_cpu(h->length) & 0x00ffffff;
-		pi->vnr  = 0;
+		pi->size = be32_to_cpu(h->length);
+		pi->vnr = 0;
 	} else if (header_size == sizeof(struct p_header80) &&
 		   *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) {
 		struct p_header80 *h = header;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2011-09-28  9:21 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-23 14:31 [RFC 00/10] drbd: part 10 of adding multiple volume support to drbd Philipp Reisner
2011-09-23 14:31 ` [PATCH 01/10] drbd: drbd_send_ping(), drbd_send_ping(): Return 0 upon success and an error code otherwise Philipp Reisner
2011-09-23 14:31 ` [PATCH 02/10] drbd: Introduce new primitives for sending commands Philipp Reisner
2011-09-23 14:31 ` [PATCH 03/10] drbd: Introduce drbd_header_size() Philipp Reisner
2011-09-23 14:31 ` [PATCH 04/10] drbd: Replace and remove old primitives Philipp Reisner
2011-09-23 17:33   ` Kyle Moffett
2011-09-27  9:34     ` Philipp Reisner
2011-09-23 14:31 ` [PATCH 05/10] drbd: Remove now-unused int_dig_out buffer Philipp Reisner
2011-09-23 14:31 ` [PATCH 06/10] drbd: Remove some fixed header size assumptions Philipp Reisner
2011-09-23 14:31 ` [PATCH 07/10] drbd: Remove headers from on-the-wire data structures (struct p_*) Philipp Reisner
2011-09-23 17:38   ` Kyle Moffett
2011-09-27  9:34     ` Philipp Reisner
2011-09-23 14:31 ` [PATCH 08/10] drbd: Introduce protocol version 100 headers Philipp Reisner
2011-09-23 17:42   ` Kyle Moffett
2011-09-27  9:34     ` Philipp Reisner
2011-09-23 14:31 ` [PATCH 09/10] drbd: Remove volume numbers from struct p_header95 Philipp Reisner
2011-09-23 17:28   ` Kyle Moffett
2011-09-27  9:34     ` Philipp Reisner
2011-09-28  4:26       ` Kyle Moffett
2011-09-28  9:20         ` Philipp Reisner
2011-09-28  9:21           ` [PATCH 9/9] drbd: Removed outdated comments and code that envisioned VNRs in header 95 Philipp Reisner
2011-09-23 14:31 ` [PATCH 10/10] drbd: For protocol versions before 100, use mixed header versions Philipp Reisner
2011-09-23 17:24   ` Kyle Moffett

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.