All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
@ 2011-08-25 15:06 Philipp Reisner
  2011-08-25 15:06 ` [PATCH 001/118] drbd: Get rid of req_validator_fn typedef Philipp Reisner
                   ` (119 more replies)
  0 siblings, 120 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:06 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 
500 patches. In this first series there are only 118 of these.

The most noticeable change is the support for multiple replicated volumes in
a single DRBD connection.  Write-ordering is obeyed among all writes in all
volumes in a single connection.  This feature is really important for users
who use DRBD for mirroring over longer distances. (Protocol A).

0001 - 0012  cleanups
0013 - 0026  replace the hash tables of drbd_requests with two interval trees
0027         have a look at the idr_for_each_entry(). Outside of drbd's directory.
0028 - 0035  introduced a new object which represents a DRBD connection;
             move a view members from the device object to the new conenction
             object
0036 - 0041  Introduce volume numbers into the protocol
0042 - 0052  cleanups; renames; 
0053         Improvements to handling of conflicting writes
0054 - 0060  cleanups; renames; 
0061 - 0064  code reorganisation
0065         IO latency bugfix
0066 - 0099  moving members from the device object to the connection object;
             converting function from the device object to the connection obj
0100 - 0118  work on the state engine to match the new object model

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

* [PATCH 001/118] drbd: Get rid of req_validator_fn typedef
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
@ 2011-08-25 15:06 ` Philipp Reisner
  2011-08-25 15:06 ` [PATCH 002/118] drbd: Remove superfluous declaration Philipp Reisner
                   ` (118 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:06 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_receiver.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 43beaca..d499aa6 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4270,11 +4270,9 @@ static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev,
 	return NULL;
 }
 
-typedef struct drbd_request *(req_validator_fn)
-	(struct drbd_conf *mdev, u64 id, sector_t sector);
-
 static int validate_req_change_req_state(struct drbd_conf *mdev,
-	u64 id, sector_t sector, req_validator_fn validator,
+	u64 id, sector_t sector,
+	struct drbd_request *(*validator)(struct drbd_conf *, u64, sector_t),
 	const char *func, enum drbd_req_event what)
 {
 	struct drbd_request *req;
-- 
1.7.4.1


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

* [PATCH 002/118] drbd: Remove superfluous declaration
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
  2011-08-25 15:06 ` [PATCH 001/118] drbd: Get rid of req_validator_fn typedef Philipp Reisner
@ 2011-08-25 15:06 ` Philipp Reisner
  2011-08-25 15:06 ` [PATCH 003/118] drbd: Consistently use block_id == ID_SYNCER for checksum based resync and online verify Philipp Reisner
                   ` (117 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:06 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 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ef2ceed..88b247e 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -689,7 +689,6 @@ struct drbd_work {
 	drbd_work_cb cb;
 };
 
-struct drbd_tl_epoch;
 struct drbd_request {
 	struct drbd_work w;
 	struct drbd_conf *mdev;
-- 
1.7.4.1


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

* [PATCH 003/118] drbd: Consistently use block_id == ID_SYNCER for checksum based resync and online verify
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
  2011-08-25 15:06 ` [PATCH 001/118] drbd: Get rid of req_validator_fn typedef Philipp Reisner
  2011-08-25 15:06 ` [PATCH 002/118] drbd: Remove superfluous declaration Philipp Reisner
@ 2011-08-25 15:06 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 004/118] drbd: Get rid of BE_DRBD_MAGIC and BE_DRBD_MAGIC_BIG Philipp Reisner
                   ` (116 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:06 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

DRBD_MAGIC has nothing to do with block ids and the funny values
computed were not actually used, anyway.

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 ++++
 drivers/block/drbd/drbd_worker.c   |    4 +---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0358e55..0c16620 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2474,7 +2474,7 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev,
 	struct p_block_req p;
 
 	p.sector   = cpu_to_be64(sector);
-	p.block_id = BE_DRBD_MAGIC + 0xbeef;
+	p.block_id = ID_SYNCER /* unused */;
 	p.blksize  = cpu_to_be32(size);
 
 	p.head.magic   = BE_DRBD_MAGIC;
@@ -2497,7 +2497,7 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size)
 	struct p_block_req p;
 
 	p.sector   = cpu_to_be64(sector);
-	p.block_id = BE_DRBD_MAGIC + 0xbabe;
+	p.block_id = ID_SYNCER /* unused */;
 	p.blksize  = cpu_to_be32(size);
 
 	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OV_REQUEST,
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d499aa6..5ed9619 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -341,6 +341,10 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 	e->size = data_size;
 	e->flags = 0;
 	e->sector = sector;
+	/*
+	 * The block_id is opaque to the receiver.  It is not endianness
+	 * converted, and sent back to the sender unchanged.
+	 */
 	e->block_id = id;
 
 	return e;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 4d3e6f6..10438c4 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -305,8 +305,6 @@ int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	void *digest;
 	int ok = 1;
 
-	D_ASSERT(e->block_id == DRBD_MAGIC + 0xbeef);
-
 	if (unlikely(cancel))
 		goto out;
 
@@ -359,7 +357,7 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 
 	/* GFP_TRY, because if there is no memory available right now, this may
 	 * be rescheduled for later. It is "only" background resync, after all. */
-	e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY);
+	e = drbd_alloc_ee(mdev, ID_SYNCER /* unused */, sector, size, GFP_TRY);
 	if (!e)
 		goto defer;
 
-- 
1.7.4.1


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

* [PATCH 004/118] drbd: Get rid of BE_DRBD_MAGIC and BE_DRBD_MAGIC_BIG
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (2 preceding siblings ...)
  2011-08-25 15:06 ` [PATCH 003/118] drbd: Consistently use block_id == ID_SYNCER for checksum based resync and online verify Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 005/118] drbd: Endianness convert the constants instead of the variables Philipp Reisner
                   ` (115 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Converting the constants happens at compile time.

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0c16620..2cd132a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1841,7 +1841,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
 	ERR_IF(!h) return false;
 	ERR_IF(!size) return false;
 
-	h->magic   = BE_DRBD_MAGIC;
+	h->magic   = cpu_to_be32(DRBD_MAGIC);
 	h->command = cpu_to_be16(cmd);
 	h->length  = cpu_to_be16(size-sizeof(struct p_header80));
 
@@ -1889,7 +1889,7 @@ int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
 	struct p_header80 h;
 	int ok;
 
-	h.magic   = BE_DRBD_MAGIC;
+	h.magic   = cpu_to_be32(DRBD_MAGIC);
 	h.command = cpu_to_be16(cmd);
 	h.length  = cpu_to_be16(size);
 
@@ -2477,7 +2477,7 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev,
 	p.block_id = ID_SYNCER /* unused */;
 	p.blksize  = cpu_to_be32(size);
 
-	p.head.magic   = BE_DRBD_MAGIC;
+	p.head.magic   = cpu_to_be32(DRBD_MAGIC);
 	p.head.command = cpu_to_be16(cmd);
 	p.head.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + digest_size);
 
@@ -2682,12 +2682,12 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
 	if (req->size <= DRBD_MAX_SIZE_H80_PACKET) {
-		p.head.h80.magic   = BE_DRBD_MAGIC;
+		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
 		p.head.h80.command = cpu_to_be16(P_DATA);
 		p.head.h80.length  =
 			cpu_to_be16(sizeof(p) - sizeof(union p_header) + dgs + req->size);
 	} else {
-		p.head.h95.magic   = BE_DRBD_MAGIC_BIG;
+		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 		p.head.h95.command = cpu_to_be16(P_DATA);
 		p.head.h95.length  =
 			cpu_to_be32(sizeof(p) - sizeof(union p_header) + dgs + req->size);
@@ -2767,12 +2767,12 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
 	if (e->size <= DRBD_MAX_SIZE_H80_PACKET) {
-		p.head.h80.magic   = BE_DRBD_MAGIC;
+		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
 		p.head.h80.command = cpu_to_be16(cmd);
 		p.head.h80.length  =
 			cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + dgs + e->size);
 	} else {
-		p.head.h95.magic   = BE_DRBD_MAGIC_BIG;
+		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 		p.head.h95.command = cpu_to_be16(cmd);
 		p.head.h95.length  =
 			cpu_to_be32(sizeof(p) - sizeof(struct p_header80) + dgs + e->size);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 5ed9619..69eec69 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -712,7 +712,7 @@ static enum drbd_packets drbd_recv_fp(struct drbd_conf *mdev, struct socket *soc
 
 	rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0);
 
-	if (rr == sizeof(*h) && h->magic == BE_DRBD_MAGIC)
+	if (rr == sizeof(*h) && h->magic == cpu_to_be32(DRBD_MAGIC))
 		return be16_to_cpu(h->command);
 
 	return 0xffff;
@@ -935,10 +935,10 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi
 		return false;
 	}
 
-	if (likely(h->h80.magic == BE_DRBD_MAGIC)) {
+	if (likely(h->h80.magic == cpu_to_be32(DRBD_MAGIC))) {
 		*cmd = be16_to_cpu(h->h80.command);
 		*packet_size = be16_to_cpu(h->h80.length);
-	} else if (h->h95.magic == BE_DRBD_MAGIC_BIG) {
+	} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
 		*cmd = be16_to_cpu(h->h95.command);
 		*packet_size = be32_to_cpu(h->h95.length);
 	} else {
@@ -4623,7 +4623,7 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (unlikely(h->magic != BE_DRBD_MAGIC)) {
+			if (unlikely(h->magic != cpu_to_be32(DRBD_MAGIC))) {
 				dev_err(DEV, "magic?? on meta m: 0x%08x c: %d l: %d\n",
 				    be32_to_cpu(h->magic),
 				    be16_to_cpu(h->command),
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 9e5f560..d282028 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -334,9 +334,7 @@ enum drbd_timeout_flag {
 #define UUID_JUST_CREATED ((__u64)4)
 
 #define DRBD_MAGIC 0x83740267
-#define BE_DRBD_MAGIC __constant_cpu_to_be32(DRBD_MAGIC)
 #define DRBD_MAGIC_BIG 0x835a
-#define BE_DRBD_MAGIC_BIG __constant_cpu_to_be16(DRBD_MAGIC_BIG)
 
 /* these are of type "int" */
 #define DRBD_MD_INDEX_INTERNAL -1
-- 
1.7.4.1


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

* [PATCH 005/118] drbd: Endianness convert the constants instead of the variables
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (3 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 004/118] drbd: Get rid of BE_DRBD_MAGIC and BE_DRBD_MAGIC_BIG Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 006/118] drbd: Magic reserved block_id value cleanup Philipp Reisner
                   ` (114 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Converting the constants happens at compile time.

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

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index cf0e63d..0eb17d3 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -407,7 +407,7 @@ static int drbd_al_read_tr(struct drbd_conf *mdev,
 	if (!drbd_md_sync_page_io(mdev, bdev, sector, READ))
 		return -1;
 
-	rv = (be32_to_cpu(b->magic) == DRBD_MAGIC);
+	rv = (b->magic == cpu_to_be32(DRBD_MAGIC));
 
 	for (i = 0; i < AL_EXTENTS_PT + 1; i++)
 		xor_sum ^= be32_to_cpu(b->updates[i].extent);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 2cd132a..f65b8c5 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3729,7 +3729,7 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
 		goto err;
 	}
 
-	if (be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) {
+	if (buffer->magic != cpu_to_be32(DRBD_MD_MAGIC)) {
 		dev_err(DEV, "Error while reading metadata, magic not found.\n");
 		rv = ERR_MD_INVALID;
 		goto err;
-- 
1.7.4.1


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

* [PATCH 006/118] drbd: Magic reserved block_id value cleanup
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (4 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 005/118] drbd: Endianness convert the constants instead of the variables Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 007/118] drbd: Move drbd_free_tl_hash() to drbd_main() Philipp Reisner
                   ` (113 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

The ID_VACANT definition has become entirely irrelevant by now.

The is_syncer_block_id() macro does not improve the code, so eliminated
it.

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_receiver.c |    4 ++--
 drivers/block/drbd/drbd_worker.c   |   14 ++++----------
 3 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 88b247e..c1d1755 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -87,17 +87,10 @@ extern char usermode_helper[];
  */
 #define DRBD_SIGKILL SIGHUP
 
-/* All EEs on the free list should have ID_VACANT (== 0)
- * freshly allocated EEs get !ID_VACANT (== 1)
- * so if it says "cannot dereference null pointer at address 0x00000001",
- * it is most likely one of these :( */
-
 #define ID_IN_SYNC      (4711ULL)
 #define ID_OUT_OF_SYNC  (4712ULL)
-
 #define ID_SYNCER (-1ULL)
-#define ID_VACANT 0
-#define is_syncer_block_id(id) ((id) == ID_SYNCER)
+
 #define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL)
 
 struct drbd_conf;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 69eec69..efe141e 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4308,7 +4308,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
 
-	if (is_syncer_block_id(p->block_id)) {
+	if (p->block_id == ID_SYNCER) {
 		drbd_set_in_sync(mdev, sector, blksize);
 		dec_rs_pending(mdev);
 		return true;
@@ -4349,7 +4349,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
 
-	if (is_syncer_block_id(p->block_id)) {
+	if (p->block_id == ID_SYNCER) {
 		dec_rs_pending(mdev);
 		drbd_rs_failed_io(mdev, sector, size);
 		return true;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 10438c4..43a9fef 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -85,8 +85,6 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
 	unsigned long flags = 0;
 	struct drbd_conf *mdev = e->mdev;
 
-	D_ASSERT(e->block_id != ID_VACANT);
-
 	spin_lock_irqsave(&mdev->req_lock, flags);
 	mdev->read_cnt += e->size >> 9;
 	list_del(&e->w.list);
@@ -108,18 +106,16 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	struct drbd_conf *mdev = e->mdev;
 	sector_t e_sector;
 	int do_wake;
-	int is_syncer_req;
+	u64 block_id;
 	int do_al_complete_io;
 
-	D_ASSERT(e->block_id != ID_VACANT);
-
 	/* after we moved e to done_ee,
 	 * we may no longer access it,
 	 * it may be freed/reused already!
 	 * (as soon as we release the req_lock) */
 	e_sector = e->sector;
 	do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
-	is_syncer_req = is_syncer_block_id(e->block_id);
+	block_id = e->block_id;
 
 	spin_lock_irqsave(&mdev->req_lock, flags);
 	mdev->writ_cnt += e->size >> 9;
@@ -131,15 +127,13 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	 * done from "drbd_process_done_ee" within the appropriate w.cb
 	 * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */
 
-	do_wake = is_syncer_req
-		? list_empty(&mdev->sync_ee)
-		: list_empty(&mdev->active_ee);
+	do_wake = list_empty(block_id == ID_SYNCER ? &mdev->sync_ee : &mdev->active_ee);
 
 	if (test_bit(__EE_WAS_ERROR, &e->flags))
 		__drbd_chk_io_error(mdev, false);
 	spin_unlock_irqrestore(&mdev->req_lock, flags);
 
-	if (is_syncer_req)
+	if (block_id == ID_SYNCER)
 		drbd_rs_complete_io(mdev, e_sector);
 
 	if (do_wake)
-- 
1.7.4.1


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

* [PATCH 007/118] drbd: Move drbd_free_tl_hash() to drbd_main()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (5 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 006/118] drbd: Magic reserved block_id value cleanup Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 008/118] drbd: Update outdated comment Philipp Reisner
                   ` (112 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

This is the only place where this function is used.  Make it static.

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     |   30 ++++++++++++++++++++++++++++++
 drivers/block/drbd/drbd_receiver.c |   30 ------------------------------
 3 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c1d1755..c6d8200 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1592,7 +1592,6 @@ extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev,
 extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled);
 extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed);
 extern void drbd_flush_workqueue(struct drbd_conf *mdev);
-extern void drbd_free_tl_hash(struct drbd_conf *mdev);
 
 /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to
  * mess with get_fs/set_fs, we know we are KERNEL_DS always. */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f65b8c5..eecbfc8 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -228,6 +228,36 @@ static void tl_cleanup(struct drbd_conf *mdev)
 	mdev->tl_hash_s = 0;
 }
 
+static void drbd_free_tl_hash(struct drbd_conf *mdev)
+{
+	struct hlist_head *h;
+
+	spin_lock_irq(&mdev->req_lock);
+
+	if (!mdev->tl_hash || mdev->state.conn != C_STANDALONE) {
+		spin_unlock_irq(&mdev->req_lock);
+		return;
+	}
+	/* paranoia code */
+	for (h = mdev->ee_hash; h < mdev->ee_hash + mdev->ee_hash_s; h++)
+		if (h->first)
+			dev_err(DEV, "ASSERT FAILED ee_hash[%u].first == %p, expected NULL\n",
+				(int)(h - mdev->ee_hash), h->first);
+	kfree(mdev->ee_hash);
+	mdev->ee_hash = NULL;
+	mdev->ee_hash_s = 0;
+
+	/* paranoia code */
+	for (h = mdev->tl_hash; h < mdev->tl_hash + mdev->tl_hash_s; h++)
+		if (h->first)
+			dev_err(DEV, "ASSERT FAILED tl_hash[%u] == %p, expected NULL\n",
+				(int)(h - mdev->tl_hash), h->first);
+	kfree(mdev->tl_hash);
+	mdev->tl_hash = NULL;
+	mdev->tl_hash_s = 0;
+	spin_unlock_irq(&mdev->req_lock);
+}
+
 /**
  * _tl_add_barrier() - Adds a barrier to the transfer log
  * @mdev:	DRBD device.
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index efe141e..bafc233 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3740,36 +3740,6 @@ void drbd_flush_workqueue(struct drbd_conf *mdev)
 	wait_for_completion(&barr.done);
 }
 
-void drbd_free_tl_hash(struct drbd_conf *mdev)
-{
-	struct hlist_head *h;
-
-	spin_lock_irq(&mdev->req_lock);
-
-	if (!mdev->tl_hash || mdev->state.conn != C_STANDALONE) {
-		spin_unlock_irq(&mdev->req_lock);
-		return;
-	}
-	/* paranoia code */
-	for (h = mdev->ee_hash; h < mdev->ee_hash + mdev->ee_hash_s; h++)
-		if (h->first)
-			dev_err(DEV, "ASSERT FAILED ee_hash[%u].first == %p, expected NULL\n",
-				(int)(h - mdev->ee_hash), h->first);
-	kfree(mdev->ee_hash);
-	mdev->ee_hash = NULL;
-	mdev->ee_hash_s = 0;
-
-	/* paranoia code */
-	for (h = mdev->tl_hash; h < mdev->tl_hash + mdev->tl_hash_s; h++)
-		if (h->first)
-			dev_err(DEV, "ASSERT FAILED tl_hash[%u] == %p, expected NULL\n",
-				(int)(h - mdev->tl_hash), h->first);
-	kfree(mdev->tl_hash);
-	mdev->tl_hash = NULL;
-	mdev->tl_hash_s = 0;
-	spin_unlock_irq(&mdev->req_lock);
-}
-
 static void drbd_disconnect(struct drbd_conf *mdev)
 {
 	enum drbd_fencing_p fp;
-- 
1.7.4.1


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

* [PATCH 008/118] drbd: Update outdated comment
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (6 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 007/118] drbd: Move drbd_free_tl_hash() to drbd_main() Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 009/118] drbd: Request lookup code cleanup (1) Philipp Reisner
                   ` (111 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_receiver.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bafc233..26810ce 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1512,7 +1512,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packets cmd, un
 	if (get_ldev(mdev)) {
 		/* data is submitted to disk within recv_resync_read.
 		 * corresponding put_ldev done below on error,
-		 * or in drbd_endio_write_sec. */
+		 * or in drbd_endio_sec. */
 		ok = recv_resync_read(mdev, sector, data_size);
 	} else {
 		if (__ratelimit(&drbd_ratelimit_state))
@@ -1673,7 +1673,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 	/* get_ldev(mdev) successful.
 	 * Corresponding put_ldev done either below (on various errors),
-	 * or in drbd_endio_write_sec, if we successfully submit the data at
+	 * or in drbd_endio_sec, if we successfully submit the data at
 	 * the end of this function. */
 
 	sector = be64_to_cpu(p->sector);
-- 
1.7.4.1


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

* [PATCH 009/118] drbd: Request lookup code cleanup (1)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (7 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 008/118] drbd: Update outdated comment Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 010/118] drbd: Request lookup code cleanup (2) Philipp Reisner
                   ` (110 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Move _ar_id_to_req() to drbd_receiver.c and mark it non-inline.  Remove
the leading underscores from _ar_id_to_req() and _ack_id_to_req().  Mark
ar_hash_slot() inline.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 26810ce..1684c48 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1469,6 +1469,24 @@ fail:
 	return false;
 }
 
+/* when we receive the answer for a read request,
+ * verify that we actually know about it */
+static struct drbd_request *ar_id_to_req(struct drbd_conf *mdev, u64 id,
+					 sector_t sector)
+{
+	struct hlist_head *slot = ar_hash_slot(mdev, sector);
+	struct hlist_node *n;
+	struct drbd_request *req;
+
+	hlist_for_each_entry(req, n, slot, collision) {
+		if ((unsigned long)req == (unsigned long)id) {
+			D_ASSERT(req->sector == sector);
+			return req;
+		}
+	}
+	return NULL;
+}
+
 static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
 	struct drbd_request *req;
@@ -1479,7 +1497,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	sector = be64_to_cpu(p->sector);
 
 	spin_lock_irq(&mdev->req_lock);
-	req = _ar_id_to_req(mdev, p->block_id, sector);
+	req = ar_id_to_req(mdev, p->block_id, sector);
 	spin_unlock_irq(&mdev->req_lock);
 	if (unlikely(!req)) {
 		dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
@@ -4222,8 +4240,8 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 
 /* when we receive the ACK for a write request,
  * verify that we actually know about it */
-static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev,
-	u64 id, sector_t sector)
+static struct drbd_request *ack_id_to_req(struct drbd_conf *mdev, u64 id,
+					  sector_t sector)
 {
 	struct hlist_head *slot = tl_hash_slot(mdev, sector);
 	struct hlist_node *n;
@@ -4232,7 +4250,7 @@ static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev,
 	hlist_for_each_entry(req, n, slot, collision) {
 		if ((unsigned long)req == (unsigned long)id) {
 			if (req->sector != sector) {
-				dev_err(DEV, "_ack_id_to_req: found req %p but it has "
+				dev_err(DEV, "ack_id_to_req: found req %p but it has "
 				    "wrong sector (%llus versus %llus)\n", req,
 				    (unsigned long long)req->sector,
 				    (unsigned long long)sector);
@@ -4306,7 +4324,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-		_ack_id_to_req, __func__ , what);
+					     ack_id_to_req, __func__, what);
 }
 
 static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
@@ -4326,7 +4344,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	spin_lock_irq(&mdev->req_lock);
-	req = _ack_id_to_req(mdev, p->block_id, sector);
+	req = ack_id_to_req(mdev, p->block_id, sector);
 	if (!req) {
 		spin_unlock_irq(&mdev->req_lock);
 		if (mdev->net_conf->wire_protocol == DRBD_PROT_A ||
@@ -4363,7 +4381,7 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 	    (unsigned long long)sector, be32_to_cpu(p->blksize));
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-		_ar_id_to_req, __func__ , neg_acked);
+					     ar_id_to_req, __func__ , neg_acked);
 }
 
 static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 68a234a..a773636 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -241,30 +241,13 @@ struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector)
 }
 
 /* application reads (drbd_request objects) */
-static struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector)
+static inline
+struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector)
 {
 	return mdev->app_reads_hash
 		+ ((unsigned int)(sector) % APP_R_HSIZE);
 }
 
-/* when we receive the answer for a read request,
- * verify that we actually know about it */
-static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev,
-	u64 id, sector_t sector)
-{
-	struct hlist_head *slot = ar_hash_slot(mdev, sector);
-	struct hlist_node *n;
-	struct drbd_request *req;
-
-	hlist_for_each_entry(req, n, slot, collision) {
-		if ((unsigned long)req == (unsigned long)id) {
-			D_ASSERT(req->sector == sector);
-			return req;
-		}
-	}
-	return NULL;
-}
-
 static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bio *bio_src)
 {
 	struct bio *bio;
-- 
1.7.4.1


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

* [PATCH 010/118] drbd: Request lookup code cleanup (2)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (8 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 009/118] drbd: Request lookup code cleanup (1) Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 011/118] drbd: Request lookup code cleanup (3) Philipp Reisner
                   ` (109 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Unify the ar_id_to_req() and ack_id_to_req() functions: make both fail
if the consistency check fails.  Move the request lookup code now
duplicated in both functions into its own function.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1684c48..ae32aed 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1469,24 +1469,39 @@ fail:
 	return false;
 }
 
-/* when we receive the answer for a read request,
- * verify that we actually know about it */
-static struct drbd_request *ar_id_to_req(struct drbd_conf *mdev, u64 id,
-					 sector_t sector)
+static struct drbd_request *
+find_request(struct drbd_conf *mdev,
+	     struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
+	     u64 id, sector_t sector, const char *func)
 {
-	struct hlist_head *slot = ar_hash_slot(mdev, sector);
+	struct hlist_head *slot = hash_slot(mdev, sector);
 	struct hlist_node *n;
 	struct drbd_request *req;
 
 	hlist_for_each_entry(req, n, slot, collision) {
-		if ((unsigned long)req == (unsigned long)id) {
-			D_ASSERT(req->sector == sector);
-			return req;
+		if ((unsigned long)req != (unsigned long)id)
+			continue;
+		if (req->sector != sector) {
+			dev_err(DEV, "%s: found request %lu but it has "
+				"wrong sector (%llus versus %llus)\n",
+				func, (unsigned long)req,
+				(unsigned long long)req->sector,
+				(unsigned long long)sector);
+			break;
 		}
+		return req;
 	}
 	return NULL;
 }
 
+/* when we receive the answer for a read request,
+ * verify that we actually know about it */
+static struct drbd_request *ar_id_to_req(struct drbd_conf *mdev, u64 id,
+					 sector_t sector)
+{
+	return find_request(mdev, ar_hash_slot, id, sector, __func__);
+}
+
 static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
 	struct drbd_request *req;
@@ -4243,23 +4258,7 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 static struct drbd_request *ack_id_to_req(struct drbd_conf *mdev, u64 id,
 					  sector_t sector)
 {
-	struct hlist_head *slot = tl_hash_slot(mdev, sector);
-	struct hlist_node *n;
-	struct drbd_request *req;
-
-	hlist_for_each_entry(req, n, slot, collision) {
-		if ((unsigned long)req == (unsigned long)id) {
-			if (req->sector != sector) {
-				dev_err(DEV, "ack_id_to_req: found req %p but it has "
-				    "wrong sector (%llus versus %llus)\n", req,
-				    (unsigned long long)req->sector,
-				    (unsigned long long)sector);
-				break;
-			}
-			return req;
-		}
-	}
-	return NULL;
+	return find_request(mdev, tl_hash_slot, id, sector, __func__);
 }
 
 static int validate_req_change_req_state(struct drbd_conf *mdev,
-- 
1.7.4.1


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

* [PATCH 011/118] drbd: Request lookup code cleanup (3)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (9 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 010/118] drbd: Request lookup code cleanup (2) Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 012/118] drbd: Request lookup code cleanup (4) Philipp Reisner
                   ` (108 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Get rid of the ar_id_to_req() and ack_id_to_req() wrappers.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index ae32aed..84c8d94 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1494,14 +1494,6 @@ find_request(struct drbd_conf *mdev,
 	return NULL;
 }
 
-/* when we receive the answer for a read request,
- * verify that we actually know about it */
-static struct drbd_request *ar_id_to_req(struct drbd_conf *mdev, u64 id,
-					 sector_t sector)
-{
-	return find_request(mdev, ar_hash_slot, id, sector, __func__);
-}
-
 static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
 	struct drbd_request *req;
@@ -1512,7 +1504,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	sector = be64_to_cpu(p->sector);
 
 	spin_lock_irq(&mdev->req_lock);
-	req = ar_id_to_req(mdev, p->block_id, sector);
+	req = find_request(mdev, ar_hash_slot, p->block_id, sector, __func__);
 	spin_unlock_irq(&mdev->req_lock);
 	if (unlikely(!req)) {
 		dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
@@ -4253,24 +4245,16 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-/* when we receive the ACK for a write request,
- * verify that we actually know about it */
-static struct drbd_request *ack_id_to_req(struct drbd_conf *mdev, u64 id,
-					  sector_t sector)
-{
-	return find_request(mdev, tl_hash_slot, id, sector, __func__);
-}
-
 static int validate_req_change_req_state(struct drbd_conf *mdev,
 	u64 id, sector_t sector,
-	struct drbd_request *(*validator)(struct drbd_conf *, u64, sector_t),
+	struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
 	const char *func, enum drbd_req_event what)
 {
 	struct drbd_request *req;
 	struct bio_and_error m;
 
 	spin_lock_irq(&mdev->req_lock);
-	req = validator(mdev, id, sector);
+	req = find_request(mdev, hash_slot, id, sector, func);
 	if (unlikely(!req)) {
 		spin_unlock_irq(&mdev->req_lock);
 
@@ -4323,7 +4307,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     ack_id_to_req, __func__, what);
+					     tl_hash_slot, __func__, what);
 }
 
 static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
@@ -4343,7 +4327,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	spin_lock_irq(&mdev->req_lock);
-	req = ack_id_to_req(mdev, p->block_id, sector);
+	req = find_request(mdev, tl_hash_slot, p->block_id, sector, __func__);
 	if (!req) {
 		spin_unlock_irq(&mdev->req_lock);
 		if (mdev->net_conf->wire_protocol == DRBD_PROT_A ||
@@ -4380,7 +4364,7 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 	    (unsigned long long)sector, be32_to_cpu(p->blksize));
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     ar_id_to_req, __func__ , neg_acked);
+					     ar_hash_slot, __func__, neg_acked);
 }
 
 static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
-- 
1.7.4.1


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

* [PATCH 012/118] drbd: Request lookup code cleanup (4)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (10 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 011/118] drbd: Request lookup code cleanup (3) Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 013/118] drbd: Add interval tree data structure Philipp Reisner
                   ` (107 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Factor out duplicate code in got_NegAck().

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 84c8d94..8e7875e 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1472,7 +1472,7 @@ fail:
 static struct drbd_request *
 find_request(struct drbd_conf *mdev,
 	     struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
-	     u64 id, sector_t sector, const char *func)
+	     u64 id, sector_t sector, bool missing_ok, const char *func)
 {
 	struct hlist_head *slot = hash_slot(mdev, sector);
 	struct hlist_node *n;
@@ -1487,10 +1487,14 @@ find_request(struct drbd_conf *mdev,
 				func, (unsigned long)req,
 				(unsigned long long)req->sector,
 				(unsigned long long)sector);
-			break;
+			return NULL;
 		}
 		return req;
 	}
+	if (!missing_ok) {
+		dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func,
+			(unsigned long)id, (unsigned long long)sector);
+	}
 	return NULL;
 }
 
@@ -1504,12 +1508,10 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	sector = be64_to_cpu(p->sector);
 
 	spin_lock_irq(&mdev->req_lock);
-	req = find_request(mdev, ar_hash_slot, p->block_id, sector, __func__);
+	req = find_request(mdev, ar_hash_slot, p->block_id, sector, false, __func__);
 	spin_unlock_irq(&mdev->req_lock);
-	if (unlikely(!req)) {
-		dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
+	if (unlikely(!req))
 		return false;
-	}
 
 	/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
 	 * special casing it there for the various failure cases.
@@ -4248,18 +4250,15 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 static int validate_req_change_req_state(struct drbd_conf *mdev,
 	u64 id, sector_t sector,
 	struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
-	const char *func, enum drbd_req_event what)
+	const char *func, enum drbd_req_event what, bool missing_ok)
 {
 	struct drbd_request *req;
 	struct bio_and_error m;
 
 	spin_lock_irq(&mdev->req_lock);
-	req = find_request(mdev, hash_slot, id, sector, func);
+	req = find_request(mdev, hash_slot, id, sector, missing_ok, func);
 	if (unlikely(!req)) {
 		spin_unlock_irq(&mdev->req_lock);
-
-		dev_err(DEV, "%s: failed to find req %p, sector %llus\n", func,
-			(void *)(unsigned long)id, (unsigned long long)sector);
 		return false;
 	}
 	__req_mod(req, what, &m);
@@ -4307,7 +4306,8 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     tl_hash_slot, __func__, what);
+					     tl_hash_slot, __func__, what,
+					     false);
 }
 
 static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
@@ -4315,8 +4315,9 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	struct p_block_ack *p = (struct p_block_ack *)h;
 	sector_t sector = be64_to_cpu(p->sector);
 	int size = be32_to_cpu(p->blksize);
-	struct drbd_request *req;
-	struct bio_and_error m;
+	bool missing_ok = mdev->net_conf->wire_protocol == DRBD_PROT_A ||
+			  mdev->net_conf->wire_protocol == DRBD_PROT_B;
+	bool found;
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
 
@@ -4326,31 +4327,19 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 		return true;
 	}
 
-	spin_lock_irq(&mdev->req_lock);
-	req = find_request(mdev, tl_hash_slot, p->block_id, sector, __func__);
-	if (!req) {
-		spin_unlock_irq(&mdev->req_lock);
-		if (mdev->net_conf->wire_protocol == DRBD_PROT_A ||
-		    mdev->net_conf->wire_protocol == DRBD_PROT_B) {
-			/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
-			   The master bio might already be completed, therefore the
-			   request is no longer in the collision hash.
-			   => Do not try to validate block_id as request. */
-			/* In Protocol B we might already have got a P_RECV_ACK
-			   but then get a P_NEG_ACK after wards. */
-			drbd_set_out_of_sync(mdev, sector, size);
-			return true;
-		} else {
-			dev_err(DEV, "%s: failed to find req %p, sector %llus\n", __func__,
-				(void *)(unsigned long)p->block_id, (unsigned long long)sector);
+	found = validate_req_change_req_state(mdev, p->block_id, sector,
+					      tl_hash_slot, __func__,
+					      neg_acked, missing_ok);
+	if (!found) {
+		/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
+		   The master bio might already be completed, therefore the
+		   request is no longer in the collision hash. */
+		/* In Protocol B we might already have got a P_RECV_ACK
+		   but then get a P_NEG_ACK afterwards. */
+		if (!missing_ok)
 			return false;
-		}
+		drbd_set_out_of_sync(mdev, sector, size);
 	}
-	__req_mod(req, neg_acked, &m);
-	spin_unlock_irq(&mdev->req_lock);
-
-	if (m.bio)
-		complete_master_bio(mdev, &m);
 	return true;
 }
 
@@ -4364,7 +4353,8 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 	    (unsigned long long)sector, be32_to_cpu(p->blksize));
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     ar_hash_slot, __func__, neg_acked);
+					     ar_hash_slot, __func__, neg_acked,
+					     false);
 }
 
 static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
-- 
1.7.4.1


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

* [PATCH 013/118] drbd: Add interval tree data structure
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (11 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 012/118] drbd: Request lookup code cleanup (4) Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 014/118] drbd: Put sector and size in struct drbd_request into struct drbd_interval Philipp Reisner
                   ` (106 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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/Makefile        |    1 +
 drivers/block/drbd/drbd_interval.c |  156 ++++++++++++++++++++++++++++++++++++
 drivers/block/drbd/drbd_interval.h |   31 +++++++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 drivers/block/drbd/drbd_interval.c
 create mode 100644 drivers/block/drbd/drbd_interval.h

diff --git a/drivers/block/drbd/Makefile b/drivers/block/drbd/Makefile
index 0d3f337..cacbb04 100644
--- a/drivers/block/drbd/Makefile
+++ b/drivers/block/drbd/Makefile
@@ -1,5 +1,6 @@
 drbd-y := drbd_bitmap.o drbd_proc.o
 drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
 drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
+drbd-y += drbd_interval.o
 
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd.o
diff --git a/drivers/block/drbd/drbd_interval.c b/drivers/block/drbd/drbd_interval.c
new file mode 100644
index 0000000..2511dd9
--- /dev/null
+++ b/drivers/block/drbd/drbd_interval.c
@@ -0,0 +1,156 @@
+#include "drbd_interval.h"
+
+/**
+ * interval_end  -  return end of @node
+ */
+static inline
+sector_t interval_end(struct rb_node *node)
+{
+	struct drbd_interval *this = rb_entry(node, struct drbd_interval, rb);
+	return this->end;
+}
+
+/**
+ * update_interval_end  -  recompute end of @node
+ *
+ * The end of an interval is the highest (start + (size >> 9)) value of this
+ * node and of its children.  Called for @node and its parents whenever the end
+ * may have changed.
+ */
+static void
+update_interval_end(struct rb_node *node, void *__unused)
+{
+	struct drbd_interval *this = rb_entry(node, struct drbd_interval, rb);
+	sector_t end;
+
+	end = this->sector + (this->size >> 9);
+	if (node->rb_left) {
+		sector_t left = interval_end(node->rb_left);
+		if (left > end)
+			end = left;
+	}
+	if (node->rb_right) {
+		sector_t right = interval_end(node->rb_right);
+		if (right > end)
+			end = right;
+	}
+	this->end = end;
+}
+
+/**
+ * drbd_insert_interval  -  insert a new interval into a tree
+ */
+bool
+drbd_insert_interval(struct rb_root *root, struct drbd_interval *this)
+{
+	struct rb_node **new = &root->rb_node, *parent = NULL;
+
+	BUG_ON(!IS_ALIGNED(this->size, 512));
+
+	while (*new) {
+		struct drbd_interval *here =
+			rb_entry(*new, struct drbd_interval, rb);
+
+		parent = *new;
+		if (this->sector < here->sector)
+			new = &(*new)->rb_left;
+		else if (this->sector > here->sector)
+			new = &(*new)->rb_right;
+		else if (this < here)
+			new = &(*new)->rb_left;
+		else if (this->sector > here->sector)
+			new = &(*new)->rb_right;
+			return false;
+	}
+
+	rb_link_node(&this->rb, parent, new);
+	rb_insert_color(&this->rb, root);
+	rb_augment_insert(&this->rb, update_interval_end, NULL);
+	return true;
+}
+
+/**
+ * drbd_contains_interval  -  check if a tree contains a given interval
+ * @sector:	start sector of @interval
+ * @interval:	may not be a valid pointer
+ *
+ * Returns if the tree contains the node @interval with start sector @start.
+ * Does not dereference @interval until @interval is known to be a valid object
+ * in @tree.  Returns %false if @interval is in the tree but with a different
+ * sector number.
+ */
+bool
+drbd_contains_interval(struct rb_root *root, sector_t sector,
+		       struct drbd_interval *interval)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct drbd_interval *here =
+			rb_entry(node, struct drbd_interval, rb);
+
+		if (sector < here->sector)
+			node = node->rb_left;
+		else if (sector > here->sector)
+			node = node->rb_right;
+		else if (interval < here)
+			node = node->rb_left;
+		else if (interval > here)
+			node = node->rb_right;
+		else
+			return interval->sector == sector;
+	}
+	return false;
+}
+
+/**
+ * drbd_remove_interval  -  remove an interval from a tree
+ */
+void
+drbd_remove_interval(struct rb_root *root, struct drbd_interval *this)
+{
+	struct rb_node *deepest;
+
+	deepest = rb_augment_erase_begin(&this->rb);
+	rb_erase(&this->rb, root);
+	rb_augment_erase_end(deepest, update_interval_end, NULL);
+}
+
+/**
+ * drbd_find_overlap  - search for an interval overlapping with [sector, sector + size)
+ * @sector:	start sector
+ * @size:	size, aligned to 512 bytes
+ *
+ * Returns the interval overlapping with [sector, sector + size), or NULL.
+ * When there is more than one overlapping interval in the tree, the interval
+ * with the lowest start sector is returned.
+ */
+struct drbd_interval *
+drbd_find_overlap(struct rb_root *root, sector_t sector, unsigned int size)
+{
+	struct rb_node *node = root->rb_node;
+	struct drbd_interval *overlap = NULL;
+	sector_t end = sector + (size >> 9);
+
+	BUG_ON(!IS_ALIGNED(size, 512));
+
+	while (node) {
+		struct drbd_interval *here =
+			rb_entry(node, struct drbd_interval, rb);
+
+		if (node->rb_left &&
+		    sector < interval_end(node->rb_left)) {
+			/* Overlap if any must be on left side */
+			node = node->rb_left;
+		} else if (here->sector < end &&
+			   sector < here->sector + (here->size >> 9)) {
+			overlap = here;
+			break;
+		} else if (sector >= here->sector) {
+			/* Overlap if any must be on right side */
+			node = node->rb_right;
+		} else
+			break;
+	}
+	return overlap;
+}
diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h
new file mode 100644
index 0000000..bf8dcf7
--- /dev/null
+++ b/drivers/block/drbd/drbd_interval.h
@@ -0,0 +1,31 @@
+#ifndef __DRBD_INTERVAL_H
+#define __DRBD_INTERVAL_H
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+
+struct drbd_interval {
+	struct rb_node rb;
+	sector_t sector;	/* start sector of the interval */
+	unsigned int size;	/* size in bytes */
+	sector_t end;		/* highest interval end in subtree */
+};
+
+static inline void drbd_clear_interval(struct drbd_interval *i)
+{
+	RB_CLEAR_NODE(&i->rb);
+}
+
+static inline bool drbd_interval_empty(struct drbd_interval *i)
+{
+	return RB_EMPTY_NODE(&i->rb);
+}
+
+bool drbd_insert_interval(struct rb_root *, struct drbd_interval *);
+struct drbd_interval *drbd_find_interval(struct rb_root *, sector_t,
+					 struct drbd_interval *);
+void drbd_remove_interval(struct rb_root *, struct drbd_interval *);
+struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t,
+					unsigned int);
+
+#endif  /* __DRBD_INTERVAL_H */
-- 
1.7.4.1


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

* [PATCH 014/118] drbd: Put sector and size in struct drbd_request into struct drbd_interval
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (12 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 013/118] drbd: Add interval tree data structure Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 015/118] drbd: Use interval tree for overlapping write request detection Philipp Reisner
                   ` (105 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    5 ++-
 drivers/block/drbd/drbd_main.c     |   14 +++++-----
 drivers/block/drbd/drbd_receiver.c |    8 +++---
 drivers/block/drbd/drbd_req.c      |   48 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_req.h      |    4 +-
 drivers/block/drbd/drbd_worker.c   |    4 +-
 6 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c6d8200..d7678e8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -682,6 +682,8 @@ struct drbd_work {
 	drbd_work_cb cb;
 };
 
+#include "drbd_interval.h"
+
 struct drbd_request {
 	struct drbd_work w;
 	struct drbd_conf *mdev;
@@ -693,8 +695,7 @@ struct drbd_request {
 	struct bio *private_bio;
 
 	struct hlist_node collision;
-	sector_t sector;
-	unsigned int size;
+	struct drbd_interval i;
 	unsigned int epoch; /* barrier_nr */
 
 	/* barrier_nr: used to check on "completion" whether this req was in
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index eecbfc8..a77b4bf 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2711,19 +2711,19 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
-	if (req->size <= DRBD_MAX_SIZE_H80_PACKET) {
+	if (req->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
 		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
 		p.head.h80.command = cpu_to_be16(P_DATA);
 		p.head.h80.length  =
-			cpu_to_be16(sizeof(p) - sizeof(union p_header) + dgs + req->size);
+			cpu_to_be16(sizeof(p) - sizeof(union p_header) + dgs + req->i.size);
 	} else {
 		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 		p.head.h95.command = cpu_to_be16(P_DATA);
 		p.head.h95.length  =
-			cpu_to_be32(sizeof(p) - sizeof(union p_header) + dgs + req->size);
+			cpu_to_be32(sizeof(p) - sizeof(union p_header) + dgs + req->i.size);
 	}
 
-	p.sector   = cpu_to_be64(req->sector);
+	p.sector   = cpu_to_be64(req->i.sector);
 	p.block_id = (unsigned long)req;
 	p.seq_num  = cpu_to_be32(req->seq_num =
 				 atomic_add_return(1, &mdev->packet_seq));
@@ -2769,7 +2769,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 			if (memcmp(mdev->int_dig_out, digest, dgs)) {
 				dev_warn(DEV,
 					"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
-					(unsigned long long)req->sector, req->size);
+					(unsigned long long)req->i.sector, req->i.size);
 			}
 		} /* else if (dgs > 64) {
 		     ... Be noisy about digest too large ...
@@ -2837,8 +2837,8 @@ int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req)
 {
 	struct p_block_desc p;
 
-	p.sector  = cpu_to_be64(req->sector);
-	p.blksize = cpu_to_be32(req->size);
+	p.sector  = cpu_to_be64(req->i.sector);
+	p.blksize = cpu_to_be32(req->i.size);
 
 	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OUT_OF_SYNC, &p.head, sizeof(p));
 }
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 8e7875e..6bb1a2f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1481,11 +1481,11 @@ find_request(struct drbd_conf *mdev,
 	hlist_for_each_entry(req, n, slot, collision) {
 		if ((unsigned long)req != (unsigned long)id)
 			continue;
-		if (req->sector != sector) {
+		if (req->i.sector != sector) {
 			dev_err(DEV, "%s: found request %lu but it has "
 				"wrong sector (%llus versus %llus)\n",
 				func, (unsigned long)req,
-				(unsigned long long)req->sector,
+				(unsigned long long)req->i.sector,
 				(unsigned long long)sector);
 			return NULL;
 		}
@@ -1783,7 +1783,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 		hlist_add_head(&e->collision, ee_hash_slot(mdev, sector));
 
-#define OVERLAPS overlaps(i->sector, i->size, sector, size)
+#define OVERLAPS overlaps(i->i.sector, i->i.size, sector, size)
 		slot = tl_hash_slot(mdev, sector);
 		first = 1;
 		for (;;) {
@@ -1800,7 +1800,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 						      "	new: %llus +%u; pending: %llus +%u\n",
 						      current->comm, current->pid,
 						      (unsigned long long)sector, size,
-						      (unsigned long long)i->sector, i->size);
+						      (unsigned long long)i->i.sector, i->i.size);
 					if (i->rq_state & RQ_NET_PENDING)
 						++have_unacked;
 					++have_conflict;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 3424d67..1af11a1 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -77,10 +77,10 @@ static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const
 		 * Other places where we set out-of-sync:
 		 * READ with local io-error */
 		if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK))
-			drbd_set_out_of_sync(mdev, req->sector, req->size);
+			drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
 
 		if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS))
-			drbd_set_in_sync(mdev, req->sector, req->size);
+			drbd_set_in_sync(mdev, req->i.sector, req->i.size);
 
 		/* one might be tempted to move the drbd_al_complete_io
 		 * to the local io completion callback drbd_endio_pri.
@@ -95,12 +95,12 @@ static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const
 		if (s & RQ_LOCAL_MASK) {
 			if (get_ldev_if_state(mdev, D_FAILED)) {
 				if (s & RQ_IN_ACT_LOG)
-					drbd_al_complete_io(mdev, req->sector);
+					drbd_al_complete_io(mdev, req->i.sector);
 				put_ldev(mdev);
 			} else if (__ratelimit(&drbd_ratelimit_state)) {
 				dev_warn(DEV, "Should have called drbd_al_complete_io(, %llu), "
 				     "but my Disk seems to have failed :(\n",
-				     (unsigned long long) req->sector);
+				     (unsigned long long) req->i.sector);
 			}
 		}
 	}
@@ -155,20 +155,20 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	 * if we have the ee_hash (two_primaries) and
 	 * this has been on the network */
 	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
-		const sector_t sector = req->sector;
-		const int size = req->size;
+		const sector_t sector = req->i.sector;
+		const int size = req->i.size;
 
 		/* ASSERT:
 		 * there must be no conflicting requests, since
 		 * they must have been failed on the spot */
-#define OVERLAPS overlaps(sector, size, i->sector, i->size)
+#define OVERLAPS overlaps(sector, size, i->i.sector, i->i.size)
 		slot = tl_hash_slot(mdev, sector);
 		hlist_for_each_entry(i, n, slot, collision) {
 			if (OVERLAPS) {
 				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
 				      "other: %p %llus +%u\n",
 				      req, (unsigned long long)sector, size,
-				      i, (unsigned long long)i->sector, i->size);
+				      i, (unsigned long long)i->i.sector, i->i.size);
 			}
 		}
 
@@ -186,7 +186,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 		 * we just have to do a wake_up.  */
 #undef OVERLAPS
 #define OVERLAPS overlaps(sector, size, e->sector, e->size)
-		slot = ee_hash_slot(mdev, req->sector);
+		slot = ee_hash_slot(mdev, req->i.sector);
 		hlist_for_each_entry(e, n, slot, collision) {
 			if (OVERLAPS) {
 				wake_up(&mdev->misc_wait);
@@ -322,8 +322,8 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
 static int _req_conflicts(struct drbd_request *req)
 {
 	struct drbd_conf *mdev = req->mdev;
-	const sector_t sector = req->sector;
-	const int size = req->size;
+	const sector_t sector = req->i.sector;
+	const int size = req->i.size;
 	struct drbd_request *i;
 	struct drbd_epoch_entry *e;
 	struct hlist_node *n;
@@ -339,7 +339,7 @@ static int _req_conflicts(struct drbd_request *req)
 		goto out_no_conflict;
 	BUG_ON(mdev->tl_hash == NULL);
 
-#define OVERLAPS overlaps(i->sector, i->size, sector, size)
+#define OVERLAPS overlaps(i->i.sector, i->i.size, sector, size)
 	slot = tl_hash_slot(mdev, sector);
 	hlist_for_each_entry(i, n, slot, collision) {
 		if (OVERLAPS) {
@@ -348,7 +348,7 @@ static int _req_conflicts(struct drbd_request *req)
 			      "pending: %llus +%u\n",
 			      current->comm, current->pid,
 			      (unsigned long long)sector, size,
-			      (unsigned long long)i->sector, i->size);
+			      (unsigned long long)i->i.sector, i->i.size);
 			goto out_conflict;
 		}
 	}
@@ -430,9 +430,9 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 	case completed_ok:
 		if (bio_data_dir(req->master_bio) == WRITE)
-			mdev->writ_cnt += req->size>>9;
+			mdev->writ_cnt += req->i.size >> 9;
 		else
-			mdev->read_cnt += req->size>>9;
+			mdev->read_cnt += req->i.size >> 9;
 
 		req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK);
 		req->rq_state &= ~RQ_LOCAL_PENDING;
@@ -459,7 +459,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		break;
 
 	case read_completed_with_error:
-		drbd_set_out_of_sync(mdev, req->sector, req->size);
+		drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
 
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
@@ -491,7 +491,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		/* so we can verify the handle in the answer packet
 		 * corresponding hlist_del is in _req_may_be_done() */
-		hlist_add_head(&req->collision, ar_hash_slot(mdev, req->sector));
+		hlist_add_head(&req->collision, ar_hash_slot(mdev, req->i.sector));
 
 		set_bit(UNPLUG_REMOTE, &mdev->flags);
 
@@ -507,7 +507,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		/* assert something? */
 		/* from drbd_make_request_common only */
 
-		hlist_add_head(&req->collision, tl_hash_slot(mdev, req->sector));
+		hlist_add_head(&req->collision, tl_hash_slot(mdev, req->i.sector));
 		/* corresponding hlist_del is in _req_may_be_done() */
 
 		/* NOTE
@@ -572,7 +572,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 	case handed_over_to_network:
 		/* assert something? */
 		if (bio_data_dir(req->master_bio) == WRITE)
-			atomic_add(req->size>>9, &mdev->ap_in_flight);
+			atomic_add(req->i.size >> 9, &mdev->ap_in_flight);
 
 		if (bio_data_dir(req->master_bio) == WRITE &&
 		    mdev->net_conf->wire_protocol == DRBD_PROT_A) {
@@ -608,7 +608,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING);
 		req->rq_state |= RQ_NET_DONE;
 		if (req->rq_state & RQ_NET_SENT && req->rq_state & RQ_WRITE)
-			atomic_sub(req->size>>9, &mdev->ap_in_flight);
+			atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
 
 		/* if it is still queued, we may not complete it here.
 		 * it will be canceled soon. */
@@ -625,7 +625,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		if (what == conflict_discarded_by_peer)
 			dev_alert(DEV, "Got DiscardAck packet %llus +%u!"
 			      " DRBD is not a random data generator!\n",
-			      (unsigned long long)req->sector, req->size);
+			      (unsigned long long)req->i.sector, req->i.size);
 		req->rq_state |= RQ_NET_DONE;
 		/* fall through */
 	case write_acked_by_peer:
@@ -647,7 +647,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		req->rq_state |= RQ_NET_OK;
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
 		dec_ap_pending(mdev);
-		atomic_sub(req->size>>9, &mdev->ap_in_flight);
+		atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
 		req->rq_state &= ~RQ_NET_PENDING;
 		_req_may_be_done_not_susp(req, m);
 		break;
@@ -656,7 +656,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		/* assert something? */
 		if (req->rq_state & RQ_NET_PENDING) {
 			dec_ap_pending(mdev);
-			atomic_sub(req->size>>9, &mdev->ap_in_flight);
+			atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
 		}
 		req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING);
 
@@ -715,7 +715,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		if ((req->rq_state & RQ_NET_MASK) != 0) {
 			req->rq_state |= RQ_NET_DONE;
 			if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
-				atomic_sub(req->size>>9, &mdev->ap_in_flight);
+				atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
 		}
 		_req_may_be_done(req, m); /* Allowed while state.susp */
 		break;
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index a773636..2520186 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -272,8 +272,8 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 		req->mdev        = mdev;
 		req->master_bio  = bio_src;
 		req->epoch       = 0;
-		req->sector      = bio_src->bi_sector;
-		req->size        = bio_src->bi_size;
+		req->i.sector     = bio_src->bi_sector;
+		req->i.size      = bio_src->bi_size;
 		INIT_HLIST_NODE(&req->collision);
 		INIT_LIST_HEAD(&req->tl_requests);
 		INIT_LIST_HEAD(&req->w.list);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 43a9fef..a1eff6e 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1288,7 +1288,7 @@ int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		return 1;
 	}
 
-	ok = drbd_send_drequest(mdev, P_DATA_REQUEST, req->sector, req->size,
+	ok = drbd_send_drequest(mdev, P_DATA_REQUEST, req->i.sector, req->i.size,
 				(unsigned long)req);
 
 	if (!ok) {
@@ -1307,7 +1307,7 @@ int w_restart_disk_io(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
 
 	if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
-		drbd_al_begin_io(mdev, req->sector);
+		drbd_al_begin_io(mdev, req->i.sector);
 	/* Calling drbd_al_begin_io() out of the worker might deadlocks
 	   theoretically. Practically it can not deadlock, since this is
 	   only used when unfreezing IOs. All the extents of the requests
-- 
1.7.4.1


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

* [PATCH 015/118] drbd: Use interval tree for overlapping write request detection
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (13 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 014/118] drbd: Put sector and size in struct drbd_request into struct drbd_interval Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 016/118] drbd: Add read_requests tree Philipp Reisner
                   ` (104 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    3 ++
 drivers/block/drbd/drbd_main.c     |    1 +
 drivers/block/drbd/drbd_receiver.c |   38 +++++++++++-------------
 drivers/block/drbd/drbd_req.c      |   56 ++++++++++++++++++-----------------
 drivers/block/drbd/drbd_req.h      |    1 +
 5 files changed, 52 insertions(+), 47 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d7678e8..0583713 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1019,6 +1019,9 @@ struct drbd_conf {
 	struct hlist_head *tl_hash;
 	unsigned int tl_hash_s;
 
+	/* Interval tree of pending local write requests */
+	struct rb_root write_requests;
+
 	/* blocks to resync in this run [unit BM_BLOCK_SIZE] */
 	unsigned long rs_total;
 	/* number of resync blocks that failed in this run */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a77b4bf..4d85838 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3473,6 +3473,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	/* no need to lock access, we are still initializing this minor device. */
 	if (!tl_init(mdev))
 		goto out_no_tl;
+	mdev->write_requests = RB_ROOT;
 
 	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
 	if (!mdev->app_reads_hash)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6bb1a2f..6b072584 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1733,9 +1733,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		const int size = e->size;
 		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags);
 		DEFINE_WAIT(wait);
-		struct drbd_request *i;
-		struct hlist_node *n;
-		struct hlist_head *slot;
 		int first;
 
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
@@ -1783,30 +1780,31 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 		hlist_add_head(&e->collision, ee_hash_slot(mdev, sector));
 
-#define OVERLAPS overlaps(i->i.sector, i->i.size, sector, size)
-		slot = tl_hash_slot(mdev, sector);
 		first = 1;
 		for (;;) {
+			struct drbd_interval *i;
 			int have_unacked = 0;
 			int have_conflict = 0;
 			prepare_to_wait(&mdev->misc_wait, &wait,
 				TASK_INTERRUPTIBLE);
-			hlist_for_each_entry(i, n, slot, collision) {
-				if (OVERLAPS) {
-					/* only ALERT on first iteration,
-					 * we may be woken up early... */
-					if (first)
-						dev_alert(DEV, "%s[%u] Concurrent local write detected!"
-						      "	new: %llus +%u; pending: %llus +%u\n",
-						      current->comm, current->pid,
-						      (unsigned long long)sector, size,
-						      (unsigned long long)i->i.sector, i->i.size);
-					if (i->rq_state & RQ_NET_PENDING)
-						++have_unacked;
-					++have_conflict;
-				}
+
+			i = drbd_find_overlap(&mdev->write_requests, sector, size);
+			if (i) {
+				struct drbd_request *req2 =
+					container_of(i, struct drbd_request, i);
+
+				/* only ALERT on first iteration,
+				 * we may be woken up early... */
+				if (first)
+					dev_alert(DEV, "%s[%u] Concurrent local write detected!"
+					      "	new: %llus +%u; pending: %llus +%u\n",
+					      current->comm, current->pid,
+					      (unsigned long long)sector, size,
+					      (unsigned long long)req2->i.sector, req2->i.size);
+				if (req2->rq_state & RQ_NET_PENDING)
+					++have_unacked;
+				++have_conflict;
 			}
-#undef OVERLAPS
 			if (!have_conflict)
 				break;
 
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 1af11a1..593576f 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -135,7 +135,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	struct drbd_request *req)
 {
 	const unsigned long s = req->rq_state;
-	struct drbd_request *i;
 	struct drbd_epoch_entry *e;
 	struct hlist_node *n;
 	struct hlist_head *slot;
@@ -157,19 +156,21 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
 		const sector_t sector = req->i.sector;
 		const int size = req->i.size;
+		struct drbd_interval *i;
 
 		/* ASSERT:
 		 * there must be no conflicting requests, since
 		 * they must have been failed on the spot */
-#define OVERLAPS overlaps(sector, size, i->i.sector, i->i.size)
-		slot = tl_hash_slot(mdev, sector);
-		hlist_for_each_entry(i, n, slot, collision) {
-			if (OVERLAPS) {
-				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
-				      "other: %p %llus +%u\n",
-				      req, (unsigned long long)sector, size,
-				      i, (unsigned long long)i->i.sector, i->i.size);
-			}
+
+		i = drbd_find_overlap(&mdev->write_requests, sector, size);
+		if (i) {
+			struct drbd_request *req2 =
+				container_of(i, struct drbd_request, i);
+
+			dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
+			      "other: %p %llus +%u\n",
+			      req, (unsigned long long)sector, size,
+			      i, (unsigned long long)req2->i.sector, req2->i.size);
 		}
 
 		/* maybe "wake" those conflicting epoch entries
@@ -184,7 +185,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 		 *
 		 * anyways, if we found one,
 		 * we just have to do a wake_up.  */
-#undef OVERLAPS
 #define OVERLAPS overlaps(sector, size, e->sector, e->size)
 		slot = ee_hash_slot(mdev, req->i.sector);
 		hlist_for_each_entry(e, n, slot, collision) {
@@ -260,9 +260,11 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 
 		/* remove the request from the conflict detection
 		 * respective block_id verification hash */
-		if (!hlist_unhashed(&req->collision))
+		if (!hlist_unhashed(&req->collision)) {
 			hlist_del(&req->collision);
-		else
+			if (!drbd_interval_empty(&req->i))
+				drbd_remove_interval(&mdev->write_requests, &req->i);
+		} else
 			D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
 		/* for writes we need to do some extra housekeeping */
@@ -324,7 +326,7 @@ static int _req_conflicts(struct drbd_request *req)
 	struct drbd_conf *mdev = req->mdev;
 	const sector_t sector = req->i.sector;
 	const int size = req->i.size;
-	struct drbd_request *i;
+	struct drbd_interval *i;
 	struct drbd_epoch_entry *e;
 	struct hlist_node *n;
 	struct hlist_head *slot;
@@ -339,24 +341,23 @@ static int _req_conflicts(struct drbd_request *req)
 		goto out_no_conflict;
 	BUG_ON(mdev->tl_hash == NULL);
 
-#define OVERLAPS overlaps(i->i.sector, i->i.size, sector, size)
-	slot = tl_hash_slot(mdev, sector);
-	hlist_for_each_entry(i, n, slot, collision) {
-		if (OVERLAPS) {
-			dev_alert(DEV, "%s[%u] Concurrent local write detected! "
-			      "[DISCARD L] new: %llus +%u; "
-			      "pending: %llus +%u\n",
-			      current->comm, current->pid,
-			      (unsigned long long)sector, size,
-			      (unsigned long long)i->i.sector, i->i.size);
-			goto out_conflict;
-		}
+	i = drbd_find_overlap(&mdev->write_requests, sector, size);
+	if (i) {
+		struct drbd_request *req2 =
+			container_of(i, struct drbd_request, i);
+
+		dev_alert(DEV, "%s[%u] Concurrent local write detected! "
+		      "[DISCARD L] new: %llus +%u; "
+		      "pending: %llus +%u\n",
+		      current->comm, current->pid,
+		      (unsigned long long)sector, size,
+		      (unsigned long long)req2->i.sector, req2->i.size);
+		goto out_conflict;
 	}
 
 	if (mdev->ee_hash_s) {
 		/* now, check for overlapping requests with remote origin */
 		BUG_ON(mdev->ee_hash == NULL);
-#undef OVERLAPS
 #define OVERLAPS overlaps(e->sector, e->size, sector, size)
 		slot = ee_hash_slot(mdev, sector);
 		hlist_for_each_entry(e, n, slot, collision) {
@@ -509,6 +510,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		hlist_add_head(&req->collision, tl_hash_slot(mdev, req->i.sector));
 		/* corresponding hlist_del is in _req_may_be_done() */
+		drbd_insert_interval(&mdev->write_requests, &req->i);
 
 		/* NOTE
 		 * In case the req ended up on the transfer log before being
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 2520186..6f11624 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -275,6 +275,7 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 		req->i.sector     = bio_src->bi_sector;
 		req->i.size      = bio_src->bi_size;
 		INIT_HLIST_NODE(&req->collision);
+		drbd_clear_interval(&req->i);
 		INIT_LIST_HEAD(&req->tl_requests);
 		INIT_LIST_HEAD(&req->w.list);
 	}
-- 
1.7.4.1


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

* [PATCH 016/118] drbd: Add read_requests tree
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (14 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 015/118] drbd: Use interval tree for overlapping write request detection Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 18:02   ` [Drbd-dev] " Pawel Jakub Dawidek
  2011-08-25 15:07 ` [PATCH 017/118] drbd: Use the read and write request trees for request lookups Philipp Reisner
                   ` (103 subsequent siblings)
  119 siblings, 1 reply; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

We do not do collision detection for read requests, but we still need to
look up the request objects when we receive a package over the network.
Using the same data structure for read and write requests results in
simpler code once the tl_hash and app_reads_hash tables are removed.

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_req.c  |   13 ++++++++++---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0583713..fe15319 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1020,6 +1020,7 @@ struct drbd_conf {
 	unsigned int tl_hash_s;
 
 	/* Interval tree of pending local write requests */
+	struct rb_root read_requests;
 	struct rb_root write_requests;
 
 	/* blocks to resync in this run [unit BM_BLOCK_SIZE] */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 4d85838..c0ea5ba 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3473,6 +3473,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	/* no need to lock access, we are still initializing this minor device. */
 	if (!tl_init(mdev))
 		goto out_no_tl;
+	mdev->read_requests = RB_ROOT;
 	mdev->write_requests = RB_ROOT;
 
 	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 593576f..d2a78c4 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -260,10 +260,15 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 
 		/* remove the request from the conflict detection
 		 * respective block_id verification hash */
-		if (!hlist_unhashed(&req->collision)) {
+		if (!drbd_interval_empty(&req->i)) {
+			struct rb_root *root;
+
 			hlist_del(&req->collision);
-			if (!drbd_interval_empty(&req->i))
-				drbd_remove_interval(&mdev->write_requests, &req->i);
+			if (rw == WRITE)
+				root = &mdev->write_requests;
+			else
+				root = &mdev->read_requests;
+			drbd_remove_interval(root, &req->i);
 		} else
 			D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
@@ -332,6 +337,7 @@ static int _req_conflicts(struct drbd_request *req)
 	struct hlist_head *slot;
 
 	D_ASSERT(hlist_unhashed(&req->collision));
+	D_ASSERT(drbd_interval_empty(&req->i));
 
 	if (!get_net_conf(mdev))
 		return 0;
@@ -493,6 +499,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		/* so we can verify the handle in the answer packet
 		 * corresponding hlist_del is in _req_may_be_done() */
 		hlist_add_head(&req->collision, ar_hash_slot(mdev, req->i.sector));
+		drbd_insert_interval(&mdev->read_requests, &req->i);
 
 		set_bit(UNPLUG_REMOTE, &mdev->flags);
 
-- 
1.7.4.1


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

* [PATCH 017/118] drbd: Use the read and write request trees for request lookups
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (15 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 016/118] drbd: Add read_requests tree Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 018/118] drbd: Put sector and size in struct drbd_epoch_entry into struct drbd_interval Philipp Reisner
                   ` (102 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_interval.h |    3 +-
 drivers/block/drbd/drbd_receiver.c |   44 +++++++++++++----------------------
 2 files changed, 17 insertions(+), 30 deletions(-)

diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h
index bf8dcf7..a847b4a 100644
--- a/drivers/block/drbd/drbd_interval.h
+++ b/drivers/block/drbd/drbd_interval.h
@@ -22,8 +22,7 @@ static inline bool drbd_interval_empty(struct drbd_interval *i)
 }
 
 bool drbd_insert_interval(struct rb_root *, struct drbd_interval *);
-struct drbd_interval *drbd_find_interval(struct rb_root *, sector_t,
-					 struct drbd_interval *);
+bool drbd_contains_interval(struct rb_root *, sector_t, struct drbd_interval *);
 void drbd_remove_interval(struct rb_root *, struct drbd_interval *);
 struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t,
 					unsigned int);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6b072584..b148398 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1470,27 +1470,15 @@ fail:
 }
 
 static struct drbd_request *
-find_request(struct drbd_conf *mdev,
-	     struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
-	     u64 id, sector_t sector, bool missing_ok, const char *func)
+find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
+	     sector_t sector, bool missing_ok, const char *func)
 {
-	struct hlist_head *slot = hash_slot(mdev, sector);
-	struct hlist_node *n;
 	struct drbd_request *req;
 
-	hlist_for_each_entry(req, n, slot, collision) {
-		if ((unsigned long)req != (unsigned long)id)
-			continue;
-		if (req->i.sector != sector) {
-			dev_err(DEV, "%s: found request %lu but it has "
-				"wrong sector (%llus versus %llus)\n",
-				func, (unsigned long)req,
-				(unsigned long long)req->i.sector,
-				(unsigned long long)sector);
-			return NULL;
-		}
+	/* Request object according to our peer */
+	req = (struct drbd_request *)(unsigned long)id;
+	if (drbd_contains_interval(root, sector, &req->i))
 		return req;
-	}
 	if (!missing_ok) {
 		dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func,
 			(unsigned long)id, (unsigned long long)sector);
@@ -1508,7 +1496,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	sector = be64_to_cpu(p->sector);
 
 	spin_lock_irq(&mdev->req_lock);
-	req = find_request(mdev, ar_hash_slot, p->block_id, sector, false, __func__);
+	req = find_request(mdev, &mdev->read_requests, p->block_id, sector, false, __func__);
 	spin_unlock_irq(&mdev->req_lock);
 	if (unlikely(!req))
 		return false;
@@ -4245,16 +4233,16 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int validate_req_change_req_state(struct drbd_conf *mdev,
-	u64 id, sector_t sector,
-	struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
-	const char *func, enum drbd_req_event what, bool missing_ok)
+static int
+validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
+			      struct rb_root *root, const char *func,
+			      enum drbd_req_event what, bool missing_ok)
 {
 	struct drbd_request *req;
 	struct bio_and_error m;
 
 	spin_lock_irq(&mdev->req_lock);
-	req = find_request(mdev, hash_slot, id, sector, missing_ok, func);
+	req = find_request(mdev, root, id, sector, missing_ok, func);
 	if (unlikely(!req)) {
 		spin_unlock_irq(&mdev->req_lock);
 		return false;
@@ -4304,8 +4292,8 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     tl_hash_slot, __func__, what,
-					     false);
+					     &mdev->write_requests, __func__,
+					     what, false);
 }
 
 static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
@@ -4326,7 +4314,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 
 	found = validate_req_change_req_state(mdev, p->block_id, sector,
-					      tl_hash_slot, __func__,
+					      &mdev->write_requests, __func__,
 					      neg_acked, missing_ok);
 	if (!found) {
 		/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
@@ -4351,8 +4339,8 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 	    (unsigned long long)sector, be32_to_cpu(p->blksize));
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
-					     ar_hash_slot, __func__, neg_acked,
-					     false);
+					     &mdev->read_requests, __func__,
+					     neg_acked, false);
 }
 
 static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
-- 
1.7.4.1


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

* [PATCH 018/118] drbd: Put sector and size in struct drbd_epoch_entry into struct drbd_interval
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (16 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 017/118] drbd: Use the read and write request trees for request lookups Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 019/118] drbd: Use interval tree for overlapping epoch entry detection Philipp Reisner
                   ` (101 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    3 +-
 drivers/block/drbd/drbd_main.c     |   14 ++++++------
 drivers/block/drbd/drbd_nl.c       |    6 ++--
 drivers/block/drbd/drbd_receiver.c |   28 ++++++++++++------------
 drivers/block/drbd/drbd_req.c      |    6 ++--
 drivers/block/drbd/drbd_worker.c   |   42 ++++++++++++++++++------------------
 6 files changed, 49 insertions(+), 50 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index fe15319..94b4f6e 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -764,10 +764,9 @@ struct drbd_epoch_entry {
 	struct drbd_conf *mdev;
 	struct page *pages;
 	atomic_t pending_bios;
-	unsigned int size;
+	struct drbd_interval i;
 	/* see comments on ee flag bits below */
 	unsigned long flags;
-	sector_t sector;
 	union {
 		u64 block_id;
 		struct digest_info *digest;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c0ea5ba..0033137 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2464,8 +2464,8 @@ int drbd_send_ack(struct drbd_conf *mdev,
 	enum drbd_packets cmd, struct drbd_epoch_entry *e)
 {
 	return _drbd_send_ack(mdev, cmd,
-			      cpu_to_be64(e->sector),
-			      cpu_to_be32(e->size),
+			      cpu_to_be64(e->i.sector),
+			      cpu_to_be32(e->i.size),
 			      e->block_id);
 }
 
@@ -2671,7 +2671,7 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
 static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
 {
 	struct page *page = e->pages;
-	unsigned len = e->size;
+	unsigned len = e->i.size;
 	/* hint all but last page with MSG_MORE */
 	page_chain_for_each(page) {
 		unsigned l = min_t(unsigned, len, PAGE_SIZE);
@@ -2796,19 +2796,19 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
-	if (e->size <= DRBD_MAX_SIZE_H80_PACKET) {
+	if (e->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
 		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
 		p.head.h80.command = cpu_to_be16(cmd);
 		p.head.h80.length  =
-			cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + dgs + e->size);
+			cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
 	} else {
 		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 		p.head.h95.command = cpu_to_be16(cmd);
 		p.head.h95.length  =
-			cpu_to_be32(sizeof(p) - sizeof(struct p_header80) + dgs + e->size);
+			cpu_to_be32(sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
 	}
 
-	p.sector   = cpu_to_be64(e->sector);
+	p.sector   = cpu_to_be64(e->i.sector);
 	p.block_id = e->block_id;
 	/* p.seq_num  = 0;    No sequence numbers here.. */
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 515bcd9..98c0e9b 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2506,7 +2506,7 @@ void drbd_bcast_ee(struct drbd_conf *mdev,
 
 	if (!cn_reply) {
 		dev_err(DEV, "could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n",
-				(unsigned long long)e->sector, e->size);
+				(unsigned long long)e->i.sector, e->i.size);
 		return;
 	}
 
@@ -2516,11 +2516,11 @@ void drbd_bcast_ee(struct drbd_conf *mdev,
 	tl = tl_add_str(tl, T_dump_ee_reason, reason);
 	tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs);
 	tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs);
-	tl = tl_add_int(tl, T_ee_sector, &e->sector);
+	tl = tl_add_int(tl, T_ee_sector, &e->i.sector);
 	tl = tl_add_int(tl, T_ee_block_id, &e->block_id);
 
 	/* dump the first 32k */
-	len = min_t(unsigned, e->size, 32 << 10);
+	len = min_t(unsigned, e->i.size, 32 << 10);
 	put_unaligned(T_ee_data, tl++);
 	put_unaligned(len, tl++);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index b148398..42c0ffa 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -338,9 +338,9 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 	e->mdev = mdev;
 	e->pages = page;
 	atomic_set(&e->pending_bios, 0);
-	e->size = data_size;
+	e->i.size = data_size;
 	e->flags = 0;
-	e->sector = sector;
+	e->i.sector = sector;
 	/*
 	 * The block_id is opaque to the receiver.  It is not endianness
 	 * converted, and sent back to the sender unchanged.
@@ -1091,8 +1091,8 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
 	struct bio *bios = NULL;
 	struct bio *bio;
 	struct page *page = e->pages;
-	sector_t sector = e->sector;
-	unsigned ds = e->size;
+	sector_t sector = e->i.sector;
+	unsigned ds = e->i.size;
 	unsigned n_bios = 0;
 	unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT;
 	int err = -ENOMEM;
@@ -1107,7 +1107,7 @@ next_bio:
 		dev_err(DEV, "submit_ee: Allocation of a bio failed\n");
 		goto fail;
 	}
-	/* > e->sector, unless this is the first bio */
+	/* > e->i.sector, unless this is the first bio */
 	bio->bi_sector = sector;
 	bio->bi_bdev = mdev->ldev->backing_bdev;
 	bio->bi_rw = rw;
@@ -1414,17 +1414,17 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
 	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
-	sector_t sector = e->sector;
+	sector_t sector = e->i.sector;
 	int ok;
 
 	D_ASSERT(hlist_unhashed(&e->collision));
 
 	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
-		drbd_set_in_sync(mdev, sector, e->size);
+		drbd_set_in_sync(mdev, sector, e->i.size);
 		ok = drbd_send_ack(mdev, P_RS_WRITE_ACK, e);
 	} else {
 		/* Record failure to sync */
-		drbd_rs_failed_io(mdev, sector, e->size);
+		drbd_rs_failed_io(mdev, sector, e->i.size);
 
 		ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
 	}
@@ -1549,7 +1549,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packets cmd, un
 static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
-	sector_t sector = e->sector;
+	sector_t sector = e->i.sector;
 	int ok = 1, pcmd;
 
 	if (mdev->net_conf->wire_protocol == DRBD_PROT_C) {
@@ -1560,7 +1560,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 				P_RS_WRITE_ACK : P_WRITE_ACK;
 			ok &= drbd_send_ack(mdev, pcmd, e);
 			if (pcmd == P_RS_WRITE_ACK)
-				drbd_set_in_sync(mdev, sector, e->size);
+				drbd_set_in_sync(mdev, sector, e->i.size);
 		} else {
 			ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
 			/* we expect it to be marked out of sync anyways...
@@ -1718,7 +1718,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	} else {
 		/* don't get the req_lock yet,
 		 * we may sleep in drbd_wait_peer_seq */
-		const int size = e->size;
+		const int size = e->i.size;
 		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags);
 		DEFINE_WAIT(wait);
 		int first;
@@ -1861,10 +1861,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 	if (mdev->state.pdsk < D_INCONSISTENT) {
 		/* In case we have the only disk of the cluster, */
-		drbd_set_out_of_sync(mdev, e->sector, e->size);
+		drbd_set_out_of_sync(mdev, e->i.sector, e->i.size);
 		e->flags |= EE_CALL_AL_COMPLETE_IO;
 		e->flags &= ~EE_MAY_SET_IN_SYNC;
-		drbd_al_begin_io(mdev, e->sector);
+		drbd_al_begin_io(mdev, e->i.sector);
 	}
 
 	if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0)
@@ -1877,7 +1877,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	hlist_del_init(&e->collision);
 	spin_unlock_irq(&mdev->req_lock);
 	if (e->flags & EE_CALL_AL_COMPLETE_IO)
-		drbd_al_complete_io(mdev, e->sector);
+		drbd_al_complete_io(mdev, e->i.sector);
 
 out_interrupted:
 	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + EV_CLEANUP);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index d2a78c4..5bf93a7 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -185,7 +185,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 		 *
 		 * anyways, if we found one,
 		 * we just have to do a wake_up.  */
-#define OVERLAPS overlaps(sector, size, e->sector, e->size)
+#define OVERLAPS overlaps(sector, size, e->i.sector, e->i.size)
 		slot = ee_hash_slot(mdev, req->i.sector);
 		hlist_for_each_entry(e, n, slot, collision) {
 			if (OVERLAPS) {
@@ -364,7 +364,7 @@ static int _req_conflicts(struct drbd_request *req)
 	if (mdev->ee_hash_s) {
 		/* now, check for overlapping requests with remote origin */
 		BUG_ON(mdev->ee_hash == NULL);
-#define OVERLAPS overlaps(e->sector, e->size, sector, size)
+#define OVERLAPS overlaps(e->i.sector, e->i.size, sector, size)
 		slot = ee_hash_slot(mdev, sector);
 		hlist_for_each_entry(e, n, slot, collision) {
 			if (OVERLAPS) {
@@ -373,7 +373,7 @@ static int _req_conflicts(struct drbd_request *req)
 				      "pending: %llus +%u\n",
 				      current->comm, current->pid,
 				      (unsigned long long)sector, size,
-				      (unsigned long long)e->sector, e->size);
+				      (unsigned long long)e->i.sector, e->i.size);
 				goto out_conflict;
 			}
 		}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index a1eff6e..2b83aaf 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -86,7 +86,7 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
 	struct drbd_conf *mdev = e->mdev;
 
 	spin_lock_irqsave(&mdev->req_lock, flags);
-	mdev->read_cnt += e->size >> 9;
+	mdev->read_cnt += e->i.size >> 9;
 	list_del(&e->w.list);
 	if (list_empty(&mdev->read_ee))
 		wake_up(&mdev->ee_wait);
@@ -113,12 +113,12 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	 * we may no longer access it,
 	 * it may be freed/reused already!
 	 * (as soon as we release the req_lock) */
-	e_sector = e->sector;
+	e_sector = e->i.sector;
 	do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
 	block_id = e->block_id;
 
 	spin_lock_irqsave(&mdev->req_lock, flags);
-	mdev->writ_cnt += e->size >> 9;
+	mdev->writ_cnt += e->i.size >> 9;
 	list_del(&e->w.list); /* has been on active_ee or sync_ee */
 	list_add_tail(&e->w.list, &mdev->done_ee);
 
@@ -159,12 +159,12 @@ void drbd_endio_sec(struct bio *bio, int error)
 	if (error && __ratelimit(&drbd_ratelimit_state))
 		dev_warn(DEV, "%s: error=%d s=%llus\n",
 				is_write ? "write" : "read", error,
-				(unsigned long long)e->sector);
+				(unsigned long long)e->i.sector);
 	if (!error && !uptodate) {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_warn(DEV, "%s: setting error to -EIO s=%llus\n",
 					is_write ? "write" : "read",
-					(unsigned long long)e->sector);
+					(unsigned long long)e->i.sector);
 		/* strange behavior of some lower level drivers...
 		 * fail the request by clearing the uptodate flag,
 		 * but do not return any error?! */
@@ -265,7 +265,7 @@ void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm, struct drbd_e
 		page = tmp;
 	}
 	/* and now the last, possibly only partially used page */
-	len = e->size & (PAGE_SIZE - 1);
+	len = e->i.size & (PAGE_SIZE - 1);
 	sg_set_page(&sg, page, len ?: PAGE_SIZE, 0);
 	crypto_hash_update(&desc, &sg, sg.length);
 	crypto_hash_final(&desc, digest);
@@ -308,8 +308,8 @@ int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	digest_size = crypto_hash_digestsize(mdev->csums_tfm);
 	digest = kmalloc(digest_size, GFP_NOIO);
 	if (digest) {
-		sector_t sector = e->sector;
-		unsigned int size = e->size;
+		sector_t sector = e->i.sector;
+		unsigned int size = e->i.size;
 		drbd_csum_ee(mdev, mdev->csums_tfm, e, digest);
 		/* Free e and pages before send.
 		 * In case we block on congestion, we could otherwise run into
@@ -901,7 +901,7 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_ent
 {
 	if (drbd_ee_has_active_page(e)) {
 		/* This might happen if sendpage() has not finished */
-		int i = (e->size + PAGE_SIZE -1) >> PAGE_SHIFT;
+		int i = (e->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
 		atomic_add(i, &mdev->pp_in_use_by_net);
 		atomic_sub(i, &mdev->pp_in_use);
 		spin_lock_irq(&mdev->req_lock);
@@ -934,7 +934,7 @@ int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	} else {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "Sending NegDReply. sector=%llus.\n",
-			    (unsigned long long)e->sector);
+			    (unsigned long long)e->i.sector);
 
 		ok = drbd_send_ack(mdev, P_NEG_DREPLY, e);
 	}
@@ -966,7 +966,7 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	}
 
 	if (get_ldev_if_state(mdev, D_FAILED)) {
-		drbd_rs_complete_io(mdev, e->sector);
+		drbd_rs_complete_io(mdev, e->i.sector);
 		put_ldev(mdev);
 	}
 
@@ -985,12 +985,12 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	} else {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "Sending NegRSDReply. sector %llus.\n",
-			    (unsigned long long)e->sector);
+			    (unsigned long long)e->i.sector);
 
 		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
 
 		/* update resync data with failure */
-		drbd_rs_failed_io(mdev, e->sector, e->size);
+		drbd_rs_failed_io(mdev, e->i.sector, e->i.size);
 	}
 
 	dec_unacked(mdev);
@@ -1017,7 +1017,7 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	}
 
 	if (get_ldev(mdev)) {
-		drbd_rs_complete_io(mdev, e->sector);
+		drbd_rs_complete_io(mdev, e->i.sector);
 		put_ldev(mdev);
 	}
 
@@ -1039,9 +1039,9 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		}
 
 		if (eq) {
-			drbd_set_in_sync(mdev, e->sector, e->size);
+			drbd_set_in_sync(mdev, e->i.sector, e->i.size);
 			/* rs_same_csums unit is BM_BLOCK_SIZE */
-			mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT;
+			mdev->rs_same_csum += e->i.size >> BM_BLOCK_SHIFT;
 			ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
 		} else {
 			inc_rs_pending(mdev);
@@ -1068,8 +1068,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
-	sector_t sector = e->sector;
-	unsigned int size = e->size;
+	sector_t sector = e->i.sector;
+	unsigned int size = e->i.size;
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -1127,8 +1127,8 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
 	struct digest_info *di;
 	void *digest;
-	sector_t sector = e->sector;
-	unsigned int size = e->size;
+	sector_t sector = e->i.sector;
+	unsigned int size = e->i.size;
 	int digest_size;
 	int ok, eq = 0;
 
@@ -1141,7 +1141,7 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	/* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all
 	 * the resync lru has been cleaned up already */
 	if (get_ldev(mdev)) {
-		drbd_rs_complete_io(mdev, e->sector);
+		drbd_rs_complete_io(mdev, e->i.sector);
 		put_ldev(mdev);
 	}
 
-- 
1.7.4.1


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

* [PATCH 019/118] drbd: Use interval tree for overlapping epoch entry detection
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (17 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 018/118] drbd: Put sector and size in struct drbd_epoch_entry into struct drbd_interval Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 020/118] drbd: Remove the unused hash tables Philipp Reisner
                   ` (100 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    3 ++
 drivers/block/drbd/drbd_main.c     |    1 +
 drivers/block/drbd/drbd_receiver.c |   15 ++++++++++++
 drivers/block/drbd/drbd_req.c      |   44 +++++++++++++----------------------
 4 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 94b4f6e..535339b 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1080,6 +1080,9 @@ struct drbd_conf {
 	struct hlist_head *ee_hash; /* is proteced by req_lock! */
 	unsigned int ee_hash_s;
 
+	/* Interval tree of pending remote write requests (struct drbd_epoch_entry) */
+	struct rb_root epoch_entries;
+
 	/* this one is protected by ee_lock, single thread */
 	struct drbd_epoch_entry *last_write_w_barrier;
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0033137..18f27af 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3475,6 +3475,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 		goto out_no_tl;
 	mdev->read_requests = RB_ROOT;
 	mdev->write_requests = RB_ROOT;
+	mdev->epoch_entries = RB_ROOT;
 
 	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
 	if (!mdev->app_reads_hash)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 42c0ffa..a0fbbfc 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -334,6 +334,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 		goto fail;
 
 	INIT_HLIST_NODE(&e->collision);
+	drbd_clear_interval(&e->i);
 	e->epoch = NULL;
 	e->mdev = mdev;
 	e->pages = page;
@@ -361,6 +362,7 @@ void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, int i
 	drbd_pp_free(mdev, e->pages, is_net);
 	D_ASSERT(atomic_read(&e->pending_bios) == 0);
 	D_ASSERT(hlist_unhashed(&e->collision));
+	D_ASSERT(drbd_interval_empty(&e->i));
 	mempool_free(e, drbd_ee_mempool);
 }
 
@@ -1418,6 +1420,7 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u
 	int ok;
 
 	D_ASSERT(hlist_unhashed(&e->collision));
+	D_ASSERT(drbd_interval_empty(&e->i));
 
 	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
 		drbd_set_in_sync(mdev, sector, e->i.size);
@@ -1574,9 +1577,13 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		spin_lock_irq(&mdev->req_lock);
 		D_ASSERT(!hlist_unhashed(&e->collision));
 		hlist_del_init(&e->collision);
+		D_ASSERT(!drbd_interval_empty(&e->i));
+		drbd_remove_interval(&mdev->epoch_entries, &e->i);
+		drbd_clear_interval(&e->i);
 		spin_unlock_irq(&mdev->req_lock);
 	} else {
 		D_ASSERT(hlist_unhashed(&e->collision));
+		D_ASSERT(drbd_interval_empty(&e->i));
 	}
 
 	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
@@ -1595,6 +1602,9 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 	spin_lock_irq(&mdev->req_lock);
 	D_ASSERT(!hlist_unhashed(&e->collision));
 	hlist_del_init(&e->collision);
+	D_ASSERT(!drbd_interval_empty(&e->i));
+	drbd_remove_interval(&mdev->epoch_entries, &e->i);
+	drbd_clear_interval(&e->i);
 	spin_unlock_irq(&mdev->req_lock);
 
 	dec_unacked(mdev);
@@ -1767,6 +1777,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		spin_lock_irq(&mdev->req_lock);
 
 		hlist_add_head(&e->collision, ee_hash_slot(mdev, sector));
+		drbd_insert_interval(&mdev->epoch_entries, &e->i);
 
 		first = 1;
 		for (;;) {
@@ -1817,6 +1828,8 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 			if (signal_pending(current)) {
 				hlist_del_init(&e->collision);
+				drbd_remove_interval(&mdev->epoch_entries, &e->i);
+				drbd_clear_interval(&e->i);
 
 				spin_unlock_irq(&mdev->req_lock);
 
@@ -1875,6 +1888,8 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	spin_lock_irq(&mdev->req_lock);
 	list_del(&e->w.list);
 	hlist_del_init(&e->collision);
+	drbd_remove_interval(&mdev->epoch_entries, &e->i);
+	drbd_clear_interval(&e->i);
 	spin_unlock_irq(&mdev->req_lock);
 	if (e->flags & EE_CALL_AL_COMPLETE_IO)
 		drbd_al_complete_io(mdev, e->i.sector);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 5bf93a7..b81ce82 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -135,9 +135,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	struct drbd_request *req)
 {
 	const unsigned long s = req->rq_state;
-	struct drbd_epoch_entry *e;
-	struct hlist_node *n;
-	struct hlist_head *slot;
 
 	/* Before we can signal completion to the upper layers,
 	 * we may need to close the current epoch.
@@ -185,16 +182,10 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 		 *
 		 * anyways, if we found one,
 		 * we just have to do a wake_up.  */
-#define OVERLAPS overlaps(sector, size, e->i.sector, e->i.size)
-		slot = ee_hash_slot(mdev, req->i.sector);
-		hlist_for_each_entry(e, n, slot, collision) {
-			if (OVERLAPS) {
-				wake_up(&mdev->misc_wait);
-				break;
-			}
-		}
+		i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
+		if (i)
+			wake_up(&mdev->misc_wait);
 	}
-#undef OVERLAPS
 }
 
 void complete_master_bio(struct drbd_conf *mdev,
@@ -332,9 +323,6 @@ static int _req_conflicts(struct drbd_request *req)
 	const sector_t sector = req->i.sector;
 	const int size = req->i.size;
 	struct drbd_interval *i;
-	struct drbd_epoch_entry *e;
-	struct hlist_node *n;
-	struct hlist_head *slot;
 
 	D_ASSERT(hlist_unhashed(&req->collision));
 	D_ASSERT(drbd_interval_empty(&req->i));
@@ -364,21 +352,21 @@ static int _req_conflicts(struct drbd_request *req)
 	if (mdev->ee_hash_s) {
 		/* now, check for overlapping requests with remote origin */
 		BUG_ON(mdev->ee_hash == NULL);
-#define OVERLAPS overlaps(e->i.sector, e->i.size, sector, size)
-		slot = ee_hash_slot(mdev, sector);
-		hlist_for_each_entry(e, n, slot, collision) {
-			if (OVERLAPS) {
-				dev_alert(DEV, "%s[%u] Concurrent remote write detected!"
-				      " [DISCARD L] new: %llus +%u; "
-				      "pending: %llus +%u\n",
-				      current->comm, current->pid,
-				      (unsigned long long)sector, size,
-				      (unsigned long long)e->i.sector, e->i.size);
-				goto out_conflict;
-			}
+
+		i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
+		if (i) {
+			struct drbd_epoch_entry *e =
+				container_of(i, struct drbd_epoch_entry, i);
+
+			dev_alert(DEV, "%s[%u] Concurrent remote write detected!"
+			      " [DISCARD L] new: %llus +%u; "
+			      "pending: %llus +%u\n",
+			      current->comm, current->pid,
+			      (unsigned long long)sector, size,
+			      (unsigned long long)e->i.sector, e->i.size);
+			goto out_conflict;
 		}
 	}
-#undef OVERLAPS
 
 out_no_conflict:
 	/* this is like it should be, and what we expected.
-- 
1.7.4.1


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

* [PATCH 020/118] drbd: Remove the unused hash tables
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (18 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 019/118] drbd: Use interval tree for overlapping epoch entry detection Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 021/118] drbd: Convert all constants in enum drbd_req_event to upper case Philipp Reisner
                   ` (99 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |   13 --------
 drivers/block/drbd/drbd_main.c     |   57 ------------------------------------
 drivers/block/drbd/drbd_nl.c       |   36 +----------------------
 drivers/block/drbd/drbd_receiver.c |   27 ++++-------------
 drivers/block/drbd/drbd_req.c      |   26 ++++------------
 drivers/block/drbd/drbd_req.h      |   27 -----------------
 drivers/block/drbd/drbd_worker.c   |   11 ++++--
 7 files changed, 20 insertions(+), 177 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 535339b..0ed97ac 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -694,7 +694,6 @@ struct drbd_request {
 	 * see drbd_endio_pri(). */
 	struct bio *private_bio;
 
-	struct hlist_node collision;
 	struct drbd_interval i;
 	unsigned int epoch; /* barrier_nr */
 
@@ -759,7 +758,6 @@ struct digest_info {
 
 struct drbd_epoch_entry {
 	struct drbd_work w;
-	struct hlist_node collision;
 	struct drbd_epoch *epoch; /* for writes */
 	struct drbd_conf *mdev;
 	struct page *pages;
@@ -1015,8 +1013,6 @@ struct drbd_conf {
 	struct drbd_tl_epoch *newest_tle;
 	struct drbd_tl_epoch *oldest_tle;
 	struct list_head out_of_sequence_requests;
-	struct hlist_head *tl_hash;
-	unsigned int tl_hash_s;
 
 	/* Interval tree of pending local write requests */
 	struct rb_root read_requests;
@@ -1077,8 +1073,6 @@ struct drbd_conf {
 	struct list_head done_ee;   /* send ack */
 	struct list_head read_ee;   /* IO in progress (any read) */
 	struct list_head net_ee;    /* zero-copy network send in progress */
-	struct hlist_head *ee_hash; /* is proteced by req_lock! */
-	unsigned int ee_hash_s;
 
 	/* Interval tree of pending remote write requests (struct drbd_epoch_entry) */
 	struct rb_root epoch_entries;
@@ -1087,7 +1081,6 @@ struct drbd_conf {
 	struct drbd_epoch_entry *last_write_w_barrier;
 
 	int next_barrier_nr;
-	struct hlist_head *app_reads_hash; /* is proteced by req_lock */
 	struct list_head resync_reads;
 	atomic_t pp_in_use;		/* allocated from page pool */
 	atomic_t pp_in_use_by_net;	/* sendpage()d, still referenced by tcp */
@@ -1428,18 +1421,12 @@ struct bm_extent {
 #endif
 #endif
 
-/* Sector shift value for the "hash" functions of tl_hash and ee_hash tables.
- * With a value of 8 all IO in one 128K block make it to the same slot of the
- * hash table. */
 #define HT_SHIFT 8
 #define DRBD_MAX_BIO_SIZE (1U<<(9+HT_SHIFT))
 #define DRBD_MAX_BIO_SIZE_SAFE (1 << 12)       /* Works always = 4k */
 
 #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */
 
-/* Number of elements in the app_reads_hash */
-#define APP_R_HSIZE 15
-
 extern int  drbd_bm_init(struct drbd_conf *mdev);
 extern int  drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors, int set_new_bits);
 extern void drbd_bm_cleanup(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 18f27af..878f7d4 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -209,9 +209,6 @@ static int tl_init(struct drbd_conf *mdev)
 	mdev->newest_tle = b;
 	INIT_LIST_HEAD(&mdev->out_of_sequence_requests);
 
-	mdev->tl_hash = NULL;
-	mdev->tl_hash_s = 0;
-
 	return 1;
 }
 
@@ -223,39 +220,6 @@ static void tl_cleanup(struct drbd_conf *mdev)
 	mdev->oldest_tle = NULL;
 	kfree(mdev->unused_spare_tle);
 	mdev->unused_spare_tle = NULL;
-	kfree(mdev->tl_hash);
-	mdev->tl_hash = NULL;
-	mdev->tl_hash_s = 0;
-}
-
-static void drbd_free_tl_hash(struct drbd_conf *mdev)
-{
-	struct hlist_head *h;
-
-	spin_lock_irq(&mdev->req_lock);
-
-	if (!mdev->tl_hash || mdev->state.conn != C_STANDALONE) {
-		spin_unlock_irq(&mdev->req_lock);
-		return;
-	}
-	/* paranoia code */
-	for (h = mdev->ee_hash; h < mdev->ee_hash + mdev->ee_hash_s; h++)
-		if (h->first)
-			dev_err(DEV, "ASSERT FAILED ee_hash[%u].first == %p, expected NULL\n",
-				(int)(h - mdev->ee_hash), h->first);
-	kfree(mdev->ee_hash);
-	mdev->ee_hash = NULL;
-	mdev->ee_hash_s = 0;
-
-	/* paranoia code */
-	for (h = mdev->tl_hash; h < mdev->tl_hash + mdev->tl_hash_s; h++)
-		if (h->first)
-			dev_err(DEV, "ASSERT FAILED tl_hash[%u] == %p, expected NULL\n",
-				(int)(h - mdev->tl_hash), h->first);
-	kfree(mdev->tl_hash);
-	mdev->tl_hash = NULL;
-	mdev->tl_hash_s = 0;
-	spin_unlock_irq(&mdev->req_lock);
 }
 
 /**
@@ -475,8 +439,6 @@ void tl_clear(struct drbd_conf *mdev)
 	/* ensure bit indicating barrier is required is clear */
 	clear_bit(CREATE_BARRIER, &mdev->flags);
 
-	memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *));
-
 	spin_unlock_irq(&mdev->req_lock);
 }
 
@@ -1633,10 +1595,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 		put_ldev(mdev);
 	}
 
-	/* free tl_hash if we Got thawed and are C_STANDALONE */
-	if (ns.conn == C_STANDALONE && !is_susp(ns) && mdev->tl_hash)
-		drbd_free_tl_hash(mdev);
-
 	/* Upon network connection, we need to start the receiver */
 	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
 		drbd_thread_start(&mdev->receiver);
@@ -3317,13 +3275,6 @@ static void drbd_delete_device(unsigned int minor)
 
 	drbd_release_ee_lists(mdev);
 
-	/* should be freed on disconnect? */
-	kfree(mdev->ee_hash);
-	/*
-	mdev->ee_hash_s = 0;
-	mdev->ee_hash = NULL;
-	*/
-
 	lc_destroy(mdev->act_log);
 	lc_destroy(mdev->resync);
 
@@ -3477,10 +3428,6 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	mdev->write_requests = RB_ROOT;
 	mdev->epoch_entries = RB_ROOT;
 
-	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
-	if (!mdev->app_reads_hash)
-		goto out_no_app_reads;
-
 	mdev->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
 	if (!mdev->current_epoch)
 		goto out_no_epoch;
@@ -3493,8 +3440,6 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 /* out_whatever_else:
 	kfree(mdev->current_epoch); */
 out_no_epoch:
-	kfree(mdev->app_reads_hash);
-out_no_app_reads:
 	tl_cleanup(mdev);
 out_no_tl:
 	drbd_bm_cleanup(mdev);
@@ -3516,7 +3461,6 @@ out_no_cpumask:
 void drbd_free_mdev(struct drbd_conf *mdev)
 {
 	kfree(mdev->current_epoch);
-	kfree(mdev->app_reads_hash);
 	tl_cleanup(mdev);
 	if (mdev->bitmap) /* should no longer be there. */
 		drbd_bm_cleanup(mdev);
@@ -3524,7 +3468,6 @@ void drbd_free_mdev(struct drbd_conf *mdev)
 	put_disk(mdev->vdisk);
 	blk_cleanup_queue(mdev->rq_queue);
 	free_cpumask_var(mdev->cpu_mask);
-	drbd_free_tl_hash(mdev);
 	kfree(mdev);
 }
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 98c0e9b..5b8ebbe 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1353,14 +1353,12 @@ static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 			    struct drbd_nl_cfg_reply *reply)
 {
-	int i, ns;
+	int i;
 	enum drbd_ret_code retcode;
 	struct net_conf *new_conf = NULL;
 	struct crypto_hash *tfm = NULL;
 	struct crypto_hash *integrity_w_tfm = NULL;
 	struct crypto_hash *integrity_r_tfm = NULL;
-	struct hlist_head *new_tl_hash = NULL;
-	struct hlist_head *new_ee_hash = NULL;
 	struct drbd_conf *odev;
 	char hmac_name[CRYPTO_MAX_ALG_NAME];
 	void *int_dig_out = NULL;
@@ -1494,24 +1492,6 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		}
 	}
 
-	ns = new_conf->max_epoch_size/8;
-	if (mdev->tl_hash_s != ns) {
-		new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
-		if (!new_tl_hash) {
-			retcode = ERR_NOMEM;
-			goto fail;
-		}
-	}
-
-	ns = new_conf->max_buffers/8;
-	if (new_conf->two_primaries && (mdev->ee_hash_s != ns)) {
-		new_ee_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
-		if (!new_ee_hash) {
-			retcode = ERR_NOMEM;
-			goto fail;
-		}
-	}
-
 	((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
 
 	if (integrity_w_tfm) {
@@ -1552,18 +1532,6 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 	mdev->send_cnt = 0;
 	mdev->recv_cnt = 0;
 
-	if (new_tl_hash) {
-		kfree(mdev->tl_hash);
-		mdev->tl_hash_s = mdev->net_conf->max_epoch_size/8;
-		mdev->tl_hash = new_tl_hash;
-	}
-
-	if (new_ee_hash) {
-		kfree(mdev->ee_hash);
-		mdev->ee_hash_s = mdev->net_conf->max_buffers/8;
-		mdev->ee_hash = new_ee_hash;
-	}
-
 	crypto_free_hash(mdev->cram_hmac_tfm);
 	mdev->cram_hmac_tfm = tfm;
 
@@ -1594,8 +1562,6 @@ fail:
 	crypto_free_hash(tfm);
 	crypto_free_hash(integrity_w_tfm);
 	crypto_free_hash(integrity_r_tfm);
-	kfree(new_tl_hash);
-	kfree(new_ee_hash);
 	kfree(new_conf);
 
 	reply->ret_code = retcode;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index a0fbbfc..566317b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -333,7 +333,6 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 	if (!page)
 		goto fail;
 
-	INIT_HLIST_NODE(&e->collision);
 	drbd_clear_interval(&e->i);
 	e->epoch = NULL;
 	e->mdev = mdev;
@@ -361,7 +360,6 @@ void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, int i
 		kfree(e->digest);
 	drbd_pp_free(mdev, e->pages, is_net);
 	D_ASSERT(atomic_read(&e->pending_bios) == 0);
-	D_ASSERT(hlist_unhashed(&e->collision));
 	D_ASSERT(drbd_interval_empty(&e->i));
 	mempool_free(e, drbd_ee_mempool);
 }
@@ -1419,7 +1417,6 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u
 	sector_t sector = e->i.sector;
 	int ok;
 
-	D_ASSERT(hlist_unhashed(&e->collision));
 	D_ASSERT(drbd_interval_empty(&e->i));
 
 	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
@@ -1575,16 +1572,12 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
 	if (mdev->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->req_lock);
-		D_ASSERT(!hlist_unhashed(&e->collision));
-		hlist_del_init(&e->collision);
 		D_ASSERT(!drbd_interval_empty(&e->i));
 		drbd_remove_interval(&mdev->epoch_entries, &e->i);
 		drbd_clear_interval(&e->i);
 		spin_unlock_irq(&mdev->req_lock);
-	} else {
-		D_ASSERT(hlist_unhashed(&e->collision));
+	} else
 		D_ASSERT(drbd_interval_empty(&e->i));
-	}
 
 	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
 
@@ -1600,8 +1593,6 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
 
 	spin_lock_irq(&mdev->req_lock);
-	D_ASSERT(!hlist_unhashed(&e->collision));
-	hlist_del_init(&e->collision);
 	D_ASSERT(!drbd_interval_empty(&e->i));
 	drbd_remove_interval(&mdev->epoch_entries, &e->i);
 	drbd_clear_interval(&e->i);
@@ -1734,23 +1725,20 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		int first;
 
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-		BUG_ON(mdev->ee_hash == NULL);
-		BUG_ON(mdev->tl_hash == NULL);
 
 		/* conflict detection and handling:
 		 * 1. wait on the sequence number,
 		 *    in case this data packet overtook ACK packets.
-		 * 2. check our hash tables for conflicting requests.
-		 *    we only need to walk the tl_hash, since an ee can not
-		 *    have a conflict with an other ee: on the submitting
-		 *    node, the corresponding req had already been conflicting,
-		 *    and a conflicting req is never sent.
+		 * 2. check our interval trees for conflicting requests:
+		 *    we only need to check the write_requests tree; the
+		 *    epoch_entries tree cannot contain any overlaps because
+		 *    they were already eliminated on the submitting node.
 		 *
 		 * Note: for two_primaries, we are protocol C,
 		 * so there cannot be any request that is DONE
 		 * but still on the transfer log.
 		 *
-		 * unconditionally add to the ee_hash.
+		 * unconditionally add to the epoch_entries tree.
 		 *
 		 * if no conflicting request is found:
 		 *    submit.
@@ -1776,7 +1764,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 		spin_lock_irq(&mdev->req_lock);
 
-		hlist_add_head(&e->collision, ee_hash_slot(mdev, sector));
 		drbd_insert_interval(&mdev->epoch_entries, &e->i);
 
 		first = 1;
@@ -1827,7 +1814,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 			}
 
 			if (signal_pending(current)) {
-				hlist_del_init(&e->collision);
 				drbd_remove_interval(&mdev->epoch_entries, &e->i);
 				drbd_clear_interval(&e->i);
 
@@ -1887,7 +1873,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->req_lock);
 	list_del(&e->w.list);
-	hlist_del_init(&e->collision);
 	drbd_remove_interval(&mdev->epoch_entries, &e->i);
 	drbd_clear_interval(&e->i);
 	spin_unlock_irq(&mdev->req_lock);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index b81ce82..8541b16 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -148,9 +148,9 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 		queue_barrier(mdev);
 
 	/* we need to do the conflict detection stuff,
-	 * if we have the ee_hash (two_primaries) and
-	 * this has been on the network */
-	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
+	 * if the epoch_entries tree is non-empty and
+	 * this request has completed on the network */
+	if ((s & RQ_NET_DONE) && !RB_EMPTY_ROOT(&mdev->epoch_entries)) {
 		const sector_t sector = req->i.sector;
 		const int size = req->i.size;
 		struct drbd_interval *i;
@@ -254,7 +254,6 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 		if (!drbd_interval_empty(&req->i)) {
 			struct rb_root *root;
 
-			hlist_del(&req->collision);
 			if (rw == WRITE)
 				root = &mdev->write_requests;
 			else
@@ -313,9 +312,7 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
  * conflicting requests with local origin, and why we have to do so regardless
  * of whether we allowed multiple primaries.
  *
- * BTW, in case we only have one primary, the ee_hash is empty anyways, and the
- * second hlist_for_each_entry becomes a noop. This is even simpler than to
- * grab a reference on the net_conf, and check for the two_primaries flag...
+ * In case we only have one primary, the epoch_entries tree is empty.
  */
 static int _req_conflicts(struct drbd_request *req)
 {
@@ -324,17 +321,11 @@ static int _req_conflicts(struct drbd_request *req)
 	const int size = req->i.size;
 	struct drbd_interval *i;
 
-	D_ASSERT(hlist_unhashed(&req->collision));
 	D_ASSERT(drbd_interval_empty(&req->i));
 
 	if (!get_net_conf(mdev))
 		return 0;
 
-	/* BUG_ON */
-	ERR_IF (mdev->tl_hash_s == 0)
-		goto out_no_conflict;
-	BUG_ON(mdev->tl_hash == NULL);
-
 	i = drbd_find_overlap(&mdev->write_requests, sector, size);
 	if (i) {
 		struct drbd_request *req2 =
@@ -349,10 +340,8 @@ static int _req_conflicts(struct drbd_request *req)
 		goto out_conflict;
 	}
 
-	if (mdev->ee_hash_s) {
-		/* now, check for overlapping requests with remote origin */
-		BUG_ON(mdev->ee_hash == NULL);
-
+	if (!RB_EMPTY_ROOT(&mdev->epoch_entries)) {
+		/* check for overlapping requests with remote origin */
 		i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
 		if (i) {
 			struct drbd_epoch_entry *e =
@@ -368,7 +357,6 @@ static int _req_conflicts(struct drbd_request *req)
 		}
 	}
 
-out_no_conflict:
 	/* this is like it should be, and what we expected.
 	 * our users do behave after all... */
 	put_net_conf(mdev);
@@ -486,7 +474,6 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		/* so we can verify the handle in the answer packet
 		 * corresponding hlist_del is in _req_may_be_done() */
-		hlist_add_head(&req->collision, ar_hash_slot(mdev, req->i.sector));
 		drbd_insert_interval(&mdev->read_requests, &req->i);
 
 		set_bit(UNPLUG_REMOTE, &mdev->flags);
@@ -503,7 +490,6 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		/* assert something? */
 		/* from drbd_make_request_common only */
 
-		hlist_add_head(&req->collision, tl_hash_slot(mdev, req->i.sector));
 		/* corresponding hlist_del is in _req_may_be_done() */
 		drbd_insert_interval(&mdev->write_requests, &req->i);
 
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 6f11624..ee59174 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -222,32 +222,6 @@ enum drbd_req_state_bits {
 #define MR_READ_SHIFT  1
 #define MR_READ        (1 << MR_READ_SHIFT)
 
-/* epoch entries */
-static inline
-struct hlist_head *ee_hash_slot(struct drbd_conf *mdev, sector_t sector)
-{
-	BUG_ON(mdev->ee_hash_s == 0);
-	return mdev->ee_hash +
-		((unsigned int)(sector>>HT_SHIFT) % mdev->ee_hash_s);
-}
-
-/* transfer log (drbd_request objects) */
-static inline
-struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector)
-{
-	BUG_ON(mdev->tl_hash_s == 0);
-	return mdev->tl_hash +
-		((unsigned int)(sector>>HT_SHIFT) % mdev->tl_hash_s);
-}
-
-/* application reads (drbd_request objects) */
-static inline
-struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector)
-{
-	return mdev->app_reads_hash
-		+ ((unsigned int)(sector) % APP_R_HSIZE);
-}
-
 static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bio *bio_src)
 {
 	struct bio *bio;
@@ -274,7 +248,6 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 		req->epoch       = 0;
 		req->i.sector     = bio_src->bi_sector;
 		req->i.size      = bio_src->bi_size;
-		INIT_HLIST_NODE(&req->collision);
 		drbd_clear_interval(&req->i);
 		INIT_LIST_HEAD(&req->tl_requests);
 		INIT_LIST_HEAD(&req->w.list);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 2b83aaf..1ddf6b6 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -122,10 +122,13 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	list_del(&e->w.list); /* has been on active_ee or sync_ee */
 	list_add_tail(&e->w.list, &mdev->done_ee);
 
-	/* No hlist_del_init(&e->collision) here, we did not send the Ack yet,
-	 * neither did we wake possibly waiting conflicting requests.
-	 * done from "drbd_process_done_ee" within the appropriate w.cb
-	 * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */
+	/*
+	 * Do not remove from the epoch_entries tree here: we did not send the
+	 * Ack yet and did not wake possibly waiting conflicting requests.
+	 * Removed from the tree from "drbd_process_done_ee" within the
+	 * appropriate w.cb (e_end_block/e_end_resync_block) or from
+	 * _drbd_clear_done_ee.
+	 */
 
 	do_wake = list_empty(block_id == ID_SYNCER ? &mdev->sync_ee : &mdev->active_ee);
 
-- 
1.7.4.1


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

* [PATCH 021/118] drbd: Convert all constants in enum drbd_req_event to upper case
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (19 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 020/118] drbd: Remove the unused hash tables Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 022/118] drbd: Convert all constants in enum drbd_thread_state " Philipp Reisner
                   ` (98 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |   10 ++--
 drivers/block/drbd/drbd_main.c     |   28 ++++++------
 drivers/block/drbd/drbd_nl.c       |    2 +-
 drivers/block/drbd/drbd_receiver.c |   18 ++++----
 drivers/block/drbd/drbd_req.c      |   84 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_req.h      |   62 +++++++++++++-------------
 drivers/block/drbd/drbd_worker.c   |   22 +++++-----
 7 files changed, 113 insertions(+), 113 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0ed97ac..0d5c727 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2031,21 +2031,21 @@ static inline void drbd_thread_restart_nowait(struct drbd_thread *thi)
  * or implicit barrier packets as necessary.
  * increased:
  *  w_send_barrier
- *  _req_mod(req, queue_for_net_write or queue_for_net_read);
+ *  _req_mod(req, QUEUE_FOR_NET_WRITE or QUEUE_FOR_NET_READ);
  *    it is much easier and equally valid to count what we queue for the
  *    worker, even before it actually was queued or send.
  *    (drbd_make_request_common; recovery path on read io-error)
  * decreased:
  *  got_BarrierAck (respective tl_clear, tl_clear_barrier)
- *  _req_mod(req, data_received)
+ *  _req_mod(req, DATA_RECEIVED)
  *     [from receive_DataReply]
- *  _req_mod(req, write_acked_by_peer or recv_acked_by_peer or neg_acked)
+ *  _req_mod(req, WRITE_ACKED_BY_PEER or RECV_ACKED_BY_PEER or NEG_ACKED)
  *     [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)]
  *     for some reason it is NOT decreased in got_NegAck,
  *     but in the resulting cleanup code from report_params.
  *     we should try to remember the reason for that...
- *  _req_mod(req, send_failed or send_canceled)
- *  _req_mod(req, connection_lost_while_pending)
+ *  _req_mod(req, SEND_FAILED or SEND_CANCELED)
+ *  _req_mod(req, CONNECTION_LOST_WHILE_PENDING)
  *     [from tl_clear_barrier]
  */
 static inline void inc_ap_pending(struct drbd_conf *mdev)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 878f7d4..c5bb871 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -290,7 +290,7 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 	/* Clean up list of requests processed during current epoch */
 	list_for_each_safe(le, tle, &b->requests) {
 		r = list_entry(le, struct drbd_request, tl_requests);
-		_req_mod(r, barrier_acked);
+		_req_mod(r, BARRIER_ACKED);
 	}
 	/* There could be requests on the list waiting for completion
 	   of the write to the local disk. To avoid corruptions of
@@ -300,10 +300,10 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 	   the write acks - which would be a bug and violating write ordering.
 	   To not deadlock in case we lose connection while such requests are
 	   still pending, we need some way to find them for the
-	   _req_mode(connection_lost_while_pending).
+	   _req_mode(CONNECTION_LOST_WHILE_PENDING).
 
 	   These have been list_move'd to the out_of_sequence_requests list in
-	   _req_mod(, barrier_acked) above.
+	   _req_mod(, BARRIER_ACKED) above.
 	   */
 	list_del_init(&b->requests);
 
@@ -336,8 +336,8 @@ bail:
  * @mdev:	DRBD device.
  * @what:       The action/event to perform with all request objects
  *
- * @what might be one of connection_lost_while_pending, resend, fail_frozen_disk_io,
- * restart_frozen_disk_io.
+ * @what might be one of CONNECTION_LOST_WHILE_PENDING, RESEND, FAIL_FROZEN_DISK_IO,
+ * RESTART_FROZEN_DISK_IO.
  */
 static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 {
@@ -362,7 +362,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 		tmp = b->next;
 
 		if (n_writes) {
-			if (what == resend) {
+			if (what == RESEND) {
 				b->n_writes = n_writes;
 				if (b->w.cb == NULL) {
 					b->w.cb = w_send_barrier;
@@ -423,7 +423,7 @@ void tl_clear(struct drbd_conf *mdev)
 
 	spin_lock_irq(&mdev->req_lock);
 
-	_tl_restart(mdev, connection_lost_while_pending);
+	_tl_restart(mdev, CONNECTION_LOST_WHILE_PENDING);
 
 	/* we expect this list to be empty. */
 	D_ASSERT(list_empty(&mdev->out_of_sequence_requests));
@@ -433,7 +433,7 @@ void tl_clear(struct drbd_conf *mdev)
 		r = list_entry(le, struct drbd_request, tl_requests);
 		/* It would be nice to complete outside of spinlock.
 		 * But this is easier for now. */
-		_req_mod(r, connection_lost_while_pending);
+		_req_mod(r, CONNECTION_LOST_WHILE_PENDING);
 	}
 
 	/* ensure bit indicating barrier is required is clear */
@@ -1321,7 +1321,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags)
 {
 	enum drbd_fencing_p fp;
-	enum drbd_req_event what = nothing;
+	enum drbd_req_event what = NOTHING;
 	union drbd_state nsm = (union drbd_state){ .i = -1 };
 
 	if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
@@ -1349,12 +1349,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 	nsm.i = -1;
 	if (ns.susp_nod) {
 		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
-			what = resend;
+			what = RESEND;
 
 		if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
-			what = restart_frozen_disk_io;
+			what = RESTART_FROZEN_DISK_IO;
 
-		if (what != nothing)
+		if (what != NOTHING)
 			nsm.susp_nod = 0;
 	}
 
@@ -1373,12 +1373,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 		/* case2: The connection was established again: */
 		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
 			clear_bit(NEW_CUR_UUID, &mdev->flags);
-			what = resend;
+			what = RESEND;
 			nsm.susp_fen = 0;
 		}
 	}
 
-	if (what != nothing) {
+	if (what != NOTHING) {
 		spin_lock_irq(&mdev->req_lock);
 		_tl_restart(mdev, what);
 		nsm.i &= mdev->state.i;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 5b8ebbe..1840cbb8 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2022,7 +2022,7 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 		if (mdev->state.conn < C_CONNECTED)
 			tl_clear(mdev);
 		if (mdev->state.disk == D_DISKLESS || mdev->state.disk == D_FAILED)
-			tl_restart(mdev, fail_frozen_disk_io);
+			tl_restart(mdev, FAIL_FROZEN_DISK_IO);
 	}
 	drbd_resume_io(mdev);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 566317b..1762ef0 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -385,7 +385,7 @@ int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 
 /*
  * This function is called from _asender only_
- * but see also comments in _req_mod(,barrier_acked)
+ * but see also comments in _req_mod(,BARRIER_ACKED)
  * and receive_Barrier.
  *
  * Move entries from net_ee to done_ee, if ready.
@@ -1507,7 +1507,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	ok = recv_dless_read(mdev, req, sector, data_size);
 
 	if (ok)
-		req_mod(req, data_received);
+		req_mod(req, DATA_RECEIVED);
 	/* else: nothing. handled from drbd_disconnect...
 	 * I don't think we may complete this just yet
 	 * in case we are "on-disconnect: freeze" */
@@ -3279,7 +3279,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	cs_flags = CS_VERBOSE + (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED ? 0 : CS_HARD);
 	if (ns.pdsk == D_CONSISTENT && is_susp(ns) && ns.conn == C_CONNECTED && os.conn < C_CONNECTED &&
 	    test_bit(NEW_CUR_UUID, &mdev->flags)) {
-		/* Do not allow tl_restart(resend) for a rebooted peer. We can only allow this
+		/* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
 		   for temporal network outages! */
 		spin_unlock_irq(&mdev->req_lock);
 		dev_err(DEV, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
@@ -4272,19 +4272,19 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	switch (be16_to_cpu(h->command)) {
 	case P_RS_WRITE_ACK:
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-		what = write_acked_by_peer_and_sis;
+		what = WRITE_ACKED_BY_PEER_AND_SIS;
 		break;
 	case P_WRITE_ACK:
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-		what = write_acked_by_peer;
+		what = WRITE_ACKED_BY_PEER;
 		break;
 	case P_RECV_ACK:
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_B);
-		what = recv_acked_by_peer;
+		what = RECV_ACKED_BY_PEER;
 		break;
 	case P_DISCARD_ACK:
 		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-		what = conflict_discarded_by_peer;
+		what = CONFLICT_DISCARDED_BY_PEER;
 		break;
 	default:
 		D_ASSERT(0);
@@ -4315,7 +4315,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 
 	found = validate_req_change_req_state(mdev, p->block_id, sector,
 					      &mdev->write_requests, __func__,
-					      neg_acked, missing_ok);
+					      NEG_ACKED, missing_ok);
 	if (!found) {
 		/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
 		   The master bio might already be completed, therefore the
@@ -4340,7 +4340,7 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 
 	return validate_req_change_req_state(mdev, p->block_id, sector,
 					     &mdev->read_requests, __func__,
-					     neg_acked, false);
+					     NEG_ACKED, false);
 }
 
 static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8541b16..b3b1d4e 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -225,10 +225,10 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 		return;
 
 	if (req->master_bio) {
-		/* this is data_received (remote read)
+		/* this is DATA_RECEIVED (remote read)
 		 * or protocol C P_WRITE_ACK
 		 * or protocol B P_RECV_ACK
-		 * or protocol A "handed_over_to_network" (SendAck)
+		 * or protocol A "HANDED_OVER_TO_NETWORK" (SendAck)
 		 * or canceled or failed,
 		 * or killed from the transfer log due to connection loss.
 		 */
@@ -393,11 +393,11 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 	/* does not happen...
 	 * initialization done in drbd_req_new
-	case created:
+	case CREATED:
 		break;
 		*/
 
-	case to_be_send: /* via network */
+	case TO_BE_SENT: /* via network */
 		/* reached via drbd_make_request_common
 		 * and from w_read_retry_remote */
 		D_ASSERT(!(req->rq_state & RQ_NET_MASK));
@@ -405,13 +405,13 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		inc_ap_pending(mdev);
 		break;
 
-	case to_be_submitted: /* locally */
+	case TO_BE_SUBMITTED: /* locally */
 		/* reached via drbd_make_request_common */
 		D_ASSERT(!(req->rq_state & RQ_LOCAL_MASK));
 		req->rq_state |= RQ_LOCAL_PENDING;
 		break;
 
-	case completed_ok:
+	case COMPLETED_OK:
 		if (bio_data_dir(req->master_bio) == WRITE)
 			mdev->writ_cnt += req->i.size >> 9;
 		else
@@ -424,7 +424,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		put_ldev(mdev);
 		break;
 
-	case write_completed_with_error:
+	case WRITE_COMPLETED_WITH_ERROR:
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
@@ -433,7 +433,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		put_ldev(mdev);
 		break;
 
-	case read_ahead_completed_with_error:
+	case READ_AHEAD_COMPLETED_WITH_ERROR:
 		/* it is legal to fail READA */
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
@@ -441,7 +441,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		put_ldev(mdev);
 		break;
 
-	case read_completed_with_error:
+	case READ_COMPLETED_WITH_ERROR:
 		drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
 
 		req->rq_state |= RQ_LOCAL_COMPLETED;
@@ -459,12 +459,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			break;
 		}
 
-		/* _req_mod(req,to_be_send); oops, recursion... */
+		/* _req_mod(req,TO_BE_SENT); oops, recursion... */
 		req->rq_state |= RQ_NET_PENDING;
 		inc_ap_pending(mdev);
-		/* fall through: _req_mod(req,queue_for_net_read); */
+		/* fall through: _req_mod(req,QUEUE_FOR_NET_READ); */
 
-	case queue_for_net_read:
+	case QUEUE_FOR_NET_READ:
 		/* READ or READA, and
 		 * no local disk,
 		 * or target area marked as invalid,
@@ -486,7 +486,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		drbd_queue_work(&mdev->data.work, &req->w);
 		break;
 
-	case queue_for_net_write:
+	case QUEUE_FOR_NET_WRITE:
 		/* assert something? */
 		/* from drbd_make_request_common only */
 
@@ -533,17 +533,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		break;
 
-	case queue_for_send_oos:
+	case QUEUE_FOR_SEND_OOS:
 		req->rq_state |= RQ_NET_QUEUED;
 		req->w.cb =  w_send_oos;
 		drbd_queue_work(&mdev->data.work, &req->w);
 		break;
 
-	case oos_handed_to_network:
+	case OOS_HANDED_TO_NETWORK:
 		/* actually the same */
-	case send_canceled:
+	case SEND_CANCELED:
 		/* treat it the same */
-	case send_failed:
+	case SEND_FAILED:
 		/* real cleanup will be done from tl_clear.  just update flags
 		 * so it is no longer marked as on the worker queue */
 		req->rq_state &= ~RQ_NET_QUEUED;
@@ -552,7 +552,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		_req_may_be_done_not_susp(req, m);
 		break;
 
-	case handed_over_to_network:
+	case HANDED_OVER_TO_NETWORK:
 		/* assert something? */
 		if (bio_data_dir(req->master_bio) == WRITE)
 			atomic_add(req->i.size >> 9, &mdev->ap_in_flight);
@@ -573,17 +573,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		req->rq_state &= ~RQ_NET_QUEUED;
 		req->rq_state |= RQ_NET_SENT;
 		/* because _drbd_send_zc_bio could sleep, and may want to
-		 * dereference the bio even after the "write_acked_by_peer" and
-		 * "completed_ok" events came in, once we return from
+		 * dereference the bio even after the "WRITE_ACKED_BY_PEER" and
+		 * "COMPLETED_OK" events came in, once we return from
 		 * _drbd_send_zc_bio (drbd_send_dblock), we have to check
 		 * whether it is done already, and end it.  */
 		_req_may_be_done_not_susp(req, m);
 		break;
 
-	case read_retry_remote_canceled:
+	case READ_RETRY_REMOTE_CANCELED:
 		req->rq_state &= ~RQ_NET_QUEUED;
 		/* fall through, in case we raced with drbd_disconnect */
-	case connection_lost_while_pending:
+	case CONNECTION_LOST_WHILE_PENDING:
 		/* transfer log cleanup after connection loss */
 		/* assert something? */
 		if (req->rq_state & RQ_NET_PENDING)
@@ -599,19 +599,19 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			_req_may_be_done(req, m); /* Allowed while state.susp */
 		break;
 
-	case write_acked_by_peer_and_sis:
+	case WRITE_ACKED_BY_PEER_AND_SIS:
 		req->rq_state |= RQ_NET_SIS;
-	case conflict_discarded_by_peer:
+	case CONFLICT_DISCARDED_BY_PEER:
 		/* for discarded conflicting writes of multiple primaries,
 		 * there is no need to keep anything in the tl, potential
 		 * node crashes are covered by the activity log. */
-		if (what == conflict_discarded_by_peer)
+		if (what == CONFLICT_DISCARDED_BY_PEER)
 			dev_alert(DEV, "Got DiscardAck packet %llus +%u!"
 			      " DRBD is not a random data generator!\n",
 			      (unsigned long long)req->i.sector, req->i.size);
 		req->rq_state |= RQ_NET_DONE;
 		/* fall through */
-	case write_acked_by_peer:
+	case WRITE_ACKED_BY_PEER:
 		/* protocol C; successfully written on peer.
 		 * Nothing to do here.
 		 * We want to keep the tl in place for all protocols, to cater
@@ -623,9 +623,9 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		 * P_BARRIER_ACK, but that is an unnecessary optimization. */
 
 		/* this makes it effectively the same as for: */
-	case recv_acked_by_peer:
+	case RECV_ACKED_BY_PEER:
 		/* protocol B; pretends to be successfully written on peer.
-		 * see also notes above in handed_over_to_network about
+		 * see also notes above in HANDED_OVER_TO_NETWORK about
 		 * protocol != C */
 		req->rq_state |= RQ_NET_OK;
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
@@ -635,7 +635,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		_req_may_be_done_not_susp(req, m);
 		break;
 
-	case neg_acked:
+	case NEG_ACKED:
 		/* assert something? */
 		if (req->rq_state & RQ_NET_PENDING) {
 			dec_ap_pending(mdev);
@@ -645,17 +645,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		req->rq_state |= RQ_NET_DONE;
 		_req_may_be_done_not_susp(req, m);
-		/* else: done by handed_over_to_network */
+		/* else: done by HANDED_OVER_TO_NETWORK */
 		break;
 
-	case fail_frozen_disk_io:
+	case FAIL_FROZEN_DISK_IO:
 		if (!(req->rq_state & RQ_LOCAL_COMPLETED))
 			break;
 
 		_req_may_be_done(req, m); /* Allowed while state.susp */
 		break;
 
-	case restart_frozen_disk_io:
+	case RESTART_FROZEN_DISK_IO:
 		if (!(req->rq_state & RQ_LOCAL_COMPLETED))
 			break;
 
@@ -670,7 +670,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		drbd_queue_work(&mdev->data.work, &req->w);
 		break;
 
-	case resend:
+	case RESEND:
 		/* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK
 		   before the connection loss (B&C only); only P_BARRIER_ACK was missing.
 		   Trowing them out of the TL here by pretending we got a BARRIER_ACK
@@ -682,9 +682,9 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			}
 			break;
 		}
-		/* else, fall through to barrier_acked */
+		/* else, fall through to BARRIER_ACKED */
 
-	case barrier_acked:
+	case BARRIER_ACKED:
 		if (!(req->rq_state & RQ_WRITE))
 			break;
 
@@ -692,7 +692,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			/* barrier came in before all requests have been acked.
 			 * this is bad, because if the connection is lost now,
 			 * we won't be able to clean them up... */
-			dev_err(DEV, "FIXME (barrier_acked but pending)\n");
+			dev_err(DEV, "FIXME (BARRIER_ACKED but pending)\n");
 			list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
 		}
 		if ((req->rq_state & RQ_NET_MASK) != 0) {
@@ -703,7 +703,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		_req_may_be_done(req, m); /* Allowed while state.susp */
 		break;
 
-	case data_received:
+	case DATA_RECEIVED:
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
 		dec_ap_pending(mdev);
 		req->rq_state &= ~RQ_NET_PENDING;
@@ -924,9 +924,9 @@ allocate_barrier:
 	/* mark them early for readability.
 	 * this just sets some state flags. */
 	if (remote)
-		_req_mod(req, to_be_send);
+		_req_mod(req, TO_BE_SENT);
 	if (local)
-		_req_mod(req, to_be_submitted);
+		_req_mod(req, TO_BE_SUBMITTED);
 
 	/* check this request on the collision detection hash tables.
 	 * if we have a conflict, just complete it here.
@@ -944,11 +944,11 @@ allocate_barrier:
 		 * or READ, but not in sync.
 		 */
 		_req_mod(req, (rw == WRITE)
-				? queue_for_net_write
-				: queue_for_net_read);
+				? QUEUE_FOR_NET_WRITE
+				: QUEUE_FOR_NET_READ);
 	}
 	if (send_oos && drbd_set_out_of_sync(mdev, sector, size))
-		_req_mod(req, queue_for_send_oos);
+		_req_mod(req, QUEUE_FOR_SEND_OOS);
 
 	if (remote &&
 	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index ee59174..6dbbe89 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -77,39 +77,39 @@
  */
 
 enum drbd_req_event {
-	created,
-	to_be_send,
-	to_be_submitted,
+	CREATED,
+	TO_BE_SENT,
+	TO_BE_SUBMITTED,
 
 	/* XXX yes, now I am inconsistent...
 	 * these are not "events" but "actions"
 	 * oh, well... */
-	queue_for_net_write,
-	queue_for_net_read,
-	queue_for_send_oos,
-
-	send_canceled,
-	send_failed,
-	handed_over_to_network,
-	oos_handed_to_network,
-	connection_lost_while_pending,
-	read_retry_remote_canceled,
-	recv_acked_by_peer,
-	write_acked_by_peer,
-	write_acked_by_peer_and_sis, /* and set_in_sync */
-	conflict_discarded_by_peer,
-	neg_acked,
-	barrier_acked, /* in protocol A and B */
-	data_received, /* (remote read) */
-
-	read_completed_with_error,
-	read_ahead_completed_with_error,
-	write_completed_with_error,
-	completed_ok,
-	resend,
-	fail_frozen_disk_io,
-	restart_frozen_disk_io,
-	nothing, /* for tracing only */
+	QUEUE_FOR_NET_WRITE,
+	QUEUE_FOR_NET_READ,
+	QUEUE_FOR_SEND_OOS,
+
+	SEND_CANCELED,
+	SEND_FAILED,
+	HANDED_OVER_TO_NETWORK,
+	OOS_HANDED_TO_NETWORK,
+	CONNECTION_LOST_WHILE_PENDING,
+	READ_RETRY_REMOTE_CANCELED,
+	RECV_ACKED_BY_PEER,
+	WRITE_ACKED_BY_PEER,
+	WRITE_ACKED_BY_PEER_AND_SIS, /* and set_in_sync */
+	CONFLICT_DISCARDED_BY_PEER,
+	NEG_ACKED,
+	BARRIER_ACKED, /* in protocol A and B */
+	DATA_RECEIVED, /* (remote read) */
+
+	READ_COMPLETED_WITH_ERROR,
+	READ_AHEAD_COMPLETED_WITH_ERROR,
+	WRITE_COMPLETED_WITH_ERROR,
+	COMPLETED_OK,
+	RESEND,
+	FAIL_FROZEN_DISK_IO,
+	RESTART_FROZEN_DISK_IO,
+	NOTHING,
 };
 
 /* encoding of request states for now.  we don't actually need that many bits.
@@ -138,8 +138,8 @@ enum drbd_req_state_bits {
 	 *        recv_ack (B) or implicit "ack" (A),
 	 *        still waiting for the barrier ack.
 	 *        master_bio may already be completed and invalidated.
-	 * 11100: write_acked (C),
-	 *        data_received (for remote read, any protocol)
+	 * 11100: write acked (C),
+	 *        data received (for remote read, any protocol)
 	 *        or finally the barrier ack has arrived (B,A)...
 	 *        request can be freed
 	 * 01100: neg-acked (write, protocol C)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 1ddf6b6..550617b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -209,12 +209,12 @@ void drbd_endio_pri(struct bio *bio, int error)
 	/* to avoid recursion in __req_mod */
 	if (unlikely(error)) {
 		what = (bio_data_dir(bio) == WRITE)
-			? write_completed_with_error
+			? WRITE_COMPLETED_WITH_ERROR
 			: (bio_rw(bio) == READ)
-			  ? read_completed_with_error
-			  : read_ahead_completed_with_error;
+			  ? READ_COMPLETED_WITH_ERROR
+			  : READ_AHEAD_COMPLETED_WITH_ERROR;
 	} else
-		what = completed_ok;
+		what = COMPLETED_OK;
 
 	bio_put(req->private_bio);
 	req->private_bio = ERR_PTR(error);
@@ -238,7 +238,7 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
 	spin_lock_irq(&mdev->req_lock);
 	if (cancel || mdev->state.pdsk != D_UP_TO_DATE) {
-		_req_mod(req, read_retry_remote_canceled);
+		_req_mod(req, READ_RETRY_REMOTE_CANCELED);
 		spin_unlock_irq(&mdev->req_lock);
 		return 1;
 	}
@@ -1243,12 +1243,12 @@ int w_send_oos(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	int ok;
 
 	if (unlikely(cancel)) {
-		req_mod(req, send_canceled);
+		req_mod(req, SEND_CANCELED);
 		return 1;
 	}
 
 	ok = drbd_send_oos(mdev, req);
-	req_mod(req, oos_handed_to_network);
+	req_mod(req, OOS_HANDED_TO_NETWORK);
 
 	return ok;
 }
@@ -1265,12 +1265,12 @@ int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	int ok;
 
 	if (unlikely(cancel)) {
-		req_mod(req, send_canceled);
+		req_mod(req, SEND_CANCELED);
 		return 1;
 	}
 
 	ok = drbd_send_dblock(mdev, req);
-	req_mod(req, ok ? handed_over_to_network : send_failed);
+	req_mod(req, ok ? HANDED_OVER_TO_NETWORK : SEND_FAILED);
 
 	return ok;
 }
@@ -1287,7 +1287,7 @@ int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	int ok;
 
 	if (unlikely(cancel)) {
-		req_mod(req, send_canceled);
+		req_mod(req, SEND_CANCELED);
 		return 1;
 	}
 
@@ -1300,7 +1300,7 @@ int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		if (mdev->state.conn >= C_CONNECTED)
 			drbd_force_state(mdev, NS(conn, C_NETWORK_FAILURE));
 	}
-	req_mod(req, ok ? handed_over_to_network : send_failed);
+	req_mod(req, ok ? HANDED_OVER_TO_NETWORK : SEND_FAILED);
 
 	return ok;
 }
-- 
1.7.4.1


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

* [PATCH 022/118] drbd: Convert all constants in enum drbd_thread_state to upper case
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (20 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 021/118] drbd: Convert all constants in enum drbd_req_event to upper case Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 023/118] drbd: Replace the ERR_IF macro with an assert-like macro Philipp Reisner
                   ` (97 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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     |   38 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_receiver.c |    6 ++--
 drivers/block/drbd/drbd_worker.c   |    8 +++---
 4 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0d5c727..bb08714 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -649,10 +649,10 @@ union p_polymorph {
 
 /**********************************************************************/
 enum drbd_thread_state {
-	None,
-	Running,
-	Exiting,
-	Restarting
+	NONE,
+	RUNNING,
+	EXITING,
+	RESTARTING
 };
 
 struct drbd_thread {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c5bb871..19176a1 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1627,25 +1627,25 @@ restart:
 
 	spin_lock_irqsave(&thi->t_lock, flags);
 
-	/* if the receiver has been "Exiting", the last thing it did
+	/* if the receiver has been "EXITING", the last thing it did
 	 * was set the conn state to "StandAlone",
 	 * if now a re-connect request comes in, conn state goes C_UNCONNECTED,
 	 * and receiver thread will be "started".
-	 * drbd_thread_start needs to set "Restarting" in that case.
+	 * drbd_thread_start needs to set "RESTARTING" in that case.
 	 * t_state check and assignment needs to be within the same spinlock,
-	 * so either thread_start sees Exiting, and can remap to Restarting,
-	 * or thread_start see None, and can proceed as normal.
+	 * so either thread_start sees EXITING, and can remap to RESTARTING,
+	 * or thread_start see NONE, and can proceed as normal.
 	 */
 
-	if (thi->t_state == Restarting) {
+	if (thi->t_state == RESTARTING) {
 		dev_info(DEV, "Restarting %s\n", current->comm);
-		thi->t_state = Running;
+		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		goto restart;
 	}
 
 	thi->task = NULL;
-	thi->t_state = None;
+	thi->t_state = NONE;
 	smp_mb();
 	complete(&thi->stop);
 	spin_unlock_irqrestore(&thi->t_lock, flags);
@@ -1662,7 +1662,7 @@ static void drbd_thread_init(struct drbd_conf *mdev, struct drbd_thread *thi,
 {
 	spin_lock_init(&thi->t_lock);
 	thi->task    = NULL;
-	thi->t_state = None;
+	thi->t_state = NONE;
 	thi->function = func;
 	thi->mdev = mdev;
 }
@@ -1683,7 +1683,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 	spin_lock_irqsave(&thi->t_lock, flags);
 
 	switch (thi->t_state) {
-	case None:
+	case NONE:
 		dev_info(DEV, "Starting %s thread (from %s [%d])\n",
 				me, current->comm, current->pid);
 
@@ -1697,7 +1697,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 		init_completion(&thi->stop);
 		D_ASSERT(thi->task == NULL);
 		thi->reset_cpu_mask = 1;
-		thi->t_state = Running;
+		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
 
@@ -1712,17 +1712,17 @@ int drbd_thread_start(struct drbd_thread *thi)
 		}
 		spin_lock_irqsave(&thi->t_lock, flags);
 		thi->task = nt;
-		thi->t_state = Running;
+		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		wake_up_process(nt);
 		break;
-	case Exiting:
-		thi->t_state = Restarting;
+	case EXITING:
+		thi->t_state = RESTARTING;
 		dev_info(DEV, "Restarting %s thread (from %s [%d])\n",
 				me, current->comm, current->pid);
 		/* fall through */
-	case Running:
-	case Restarting:
+	case RUNNING:
+	case RESTARTING:
 	default:
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		break;
@@ -1736,12 +1736,12 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
 {
 	unsigned long flags;
 
-	enum drbd_thread_state ns = restart ? Restarting : Exiting;
+	enum drbd_thread_state ns = restart ? RESTARTING : EXITING;
 
 	/* may be called from state engine, holding the req lock irqsave */
 	spin_lock_irqsave(&thi->t_lock, flags);
 
-	if (thi->t_state == None) {
+	if (thi->t_state == NONE) {
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		if (restart)
 			drbd_thread_start(thi);
@@ -2504,7 +2504,7 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 
 	drop_it =   mdev->meta.socket == sock
 		|| !mdev->asender.task
-		|| get_t_state(&mdev->asender) != Running
+		|| get_t_state(&mdev->asender) != RUNNING
 		|| mdev->state.conn < C_CONNECTED;
 
 	if (drop_it)
@@ -3046,7 +3046,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 void drbd_mdev_cleanup(struct drbd_conf *mdev)
 {
 	int i;
-	if (mdev->receiver.t_state != None)
+	if (mdev->receiver.t_state != NONE)
 		dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
 				mdev->receiver.t_state);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1762ef0..1cfcc44 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -833,7 +833,7 @@ retry:
 		if (signal_pending(current)) {
 			flush_signals(current);
 			smp_rmb();
-			if (get_t_state(&mdev->receiver) == Exiting)
+			if (get_t_state(&mdev->receiver) == EXITING)
 				goto out_release_sockets;
 		}
 
@@ -3700,7 +3700,7 @@ static void drbdd(struct drbd_conf *mdev)
 	size_t shs; /* sub header size */
 	int rv;
 
-	while (get_t_state(&mdev->receiver) == Running) {
+	while (get_t_state(&mdev->receiver) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 		if (!drbd_recv_header(mdev, &cmd, &packet_size))
 			goto err_out;
@@ -4490,7 +4490,7 @@ int drbd_asender(struct drbd_thread *thi)
 	current->policy = SCHED_RR;  /* Make this a realtime task! */
 	current->rt_priority = 2;    /* more important than all other tasks */
 
-	while (get_t_state(thi) == Running) {
+	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
 			ERR_IF(!drbd_send_ping(mdev)) goto reconnect;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 550617b..c2a9285 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1617,7 +1617,7 @@ int drbd_worker(struct drbd_thread *thi)
 
 	sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev));
 
-	while (get_t_state(thi) == Running) {
+	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 
 		if (down_trylock(&mdev->data.work.s)) {
@@ -1637,12 +1637,12 @@ int drbd_worker(struct drbd_thread *thi)
 		if (intr) {
 			D_ASSERT(intr == -EINTR);
 			flush_signals(current);
-			ERR_IF (get_t_state(thi) == Running)
+			ERR_IF (get_t_state(thi) == RUNNING)
 				continue;
 			break;
 		}
 
-		if (get_t_state(thi) != Running)
+		if (get_t_state(thi) != RUNNING)
 			break;
 		/* With this break, we have done a down() but not consumed
 		   the entry from the list. The cleanup code takes care of
@@ -1704,7 +1704,7 @@ int drbd_worker(struct drbd_thread *thi)
 
 	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
 	/* _drbd_set_state only uses stop_nowait.
-	 * wait here for the Exiting receiver. */
+	 * wait here for the EXITING receiver. */
 	drbd_thread_stop(&mdev->receiver);
 	drbd_mdev_cleanup(mdev);
 
-- 
1.7.4.1


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

* [PATCH 023/118] drbd: Replace the ERR_IF macro with an assert-like macro
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (21 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 022/118] drbd: Convert all constants in enum drbd_thread_state " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 024/118] drbd: Remove some useless paranoia code Philipp Reisner
                   ` (96 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Remove the file name and line number from the syslog messages generated:
we have no duplicate function names, and no function contains the same
assertion more than once.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_actlog.c   |   21 +++++---
 drivers/block/drbd/drbd_bitmap.c   |   91 +++++++++++++++++++++++-------------
 drivers/block/drbd/drbd_int.h      |   18 +++++--
 drivers/block/drbd/drbd_main.c     |   13 +++--
 drivers/block/drbd/drbd_nl.c       |    8 ++-
 drivers/block/drbd/drbd_receiver.c |   19 +++++--
 drivers/block/drbd/drbd_worker.c   |    7 ++-
 7 files changed, 114 insertions(+), 63 deletions(-)

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 0eb17d3..9284b10 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -491,7 +491,8 @@ int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
 		unsigned int trn;
 
 		rv = drbd_al_read_tr(mdev, bdev, buffer, i);
-		ERR_IF(rv == 0) goto cancel;
+		if (!expect(rv != 0))
+			goto cancel;
 		if (rv == -1) {
 			mutex_unlock(&mdev->md_io_mutex);
 			return 0;
@@ -770,8 +771,10 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
 	nr_sectors = drbd_get_capacity(mdev->this_bdev);
 	esector = sector + (size >> 9) - 1;
 
-	ERR_IF(sector >= nr_sectors) return;
-	ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
+	if (!expect(sector < nr_sectors))
+		return;
+	if (!expect(esector < nr_sectors))
+		esector = nr_sectors - 1;
 
 	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
 
@@ -837,10 +840,10 @@ int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size,
 	nr_sectors = drbd_get_capacity(mdev->this_bdev);
 	esector = sector + (size >> 9) - 1;
 
-	ERR_IF(sector >= nr_sectors)
+	if (!expect(sector < nr_sectors))
 		goto out;
-	ERR_IF(esector >= nr_sectors)
-		esector = (nr_sectors-1);
+	if (!expect(esector < nr_sectors))
+		esector = nr_sectors - 1;
 
 	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
 
@@ -1218,8 +1221,10 @@ void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size)
 	nr_sectors = drbd_get_capacity(mdev->this_bdev);
 	esector = sector + (size >> 9) - 1;
 
-	ERR_IF(sector >= nr_sectors) return;
-	ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
+	if (!expect(sector < nr_sectors))
+		return;
+	if (!expect(esector < nr_sectors))
+		esector = nr_sectors - 1;
 
 	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
 
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 7b97629..c756b4d 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -440,7 +440,8 @@ int drbd_bm_init(struct drbd_conf *mdev)
 
 sector_t drbd_bm_capacity(struct drbd_conf *mdev)
 {
-	ERR_IF(!mdev->bitmap) return 0;
+	if (!expect(mdev->bitmap))
+		return 0;
 	return mdev->bitmap->bm_dev_capacity;
 }
 
@@ -448,7 +449,8 @@ sector_t drbd_bm_capacity(struct drbd_conf *mdev)
  */
 void drbd_bm_cleanup(struct drbd_conf *mdev)
 {
-	ERR_IF (!mdev->bitmap) return;
+	if (!expect(mdev->bitmap))
+		return;
 	bm_free_pages(mdev->bitmap->bm_pages, mdev->bitmap->bm_number_of_pages);
 	bm_vk_free(mdev->bitmap->bm_pages, (BM_P_VMALLOCED & mdev->bitmap->bm_flags));
 	kfree(mdev->bitmap);
@@ -611,7 +613,8 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits)
 	int err = 0, growing;
 	int opages_vmalloced;
 
-	ERR_IF(!b) return -ENOMEM;
+	if (!expect(b))
+		return -ENOMEM;
 
 	drbd_bm_lock(mdev, "resize", BM_LOCKED_MASK);
 
@@ -733,8 +736,10 @@ unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev)
 	unsigned long s;
 	unsigned long flags;
 
-	ERR_IF(!b) return 0;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 0;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	spin_lock_irqsave(&b->bm_lock, flags);
 	s = b->bm_set;
@@ -757,8 +762,10 @@ unsigned long drbd_bm_total_weight(struct drbd_conf *mdev)
 size_t drbd_bm_words(struct drbd_conf *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	ERR_IF(!b) return 0;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 0;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	return b->bm_words;
 }
@@ -766,7 +773,8 @@ size_t drbd_bm_words(struct drbd_conf *mdev)
 unsigned long drbd_bm_bits(struct drbd_conf *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	ERR_IF(!b) return 0;
+	if (!expect(b))
+		return 0;
 
 	return b->bm_bits;
 }
@@ -787,8 +795,10 @@ void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number,
 
 	end = offset + number;
 
-	ERR_IF(!b) return;
-	ERR_IF(!b->bm_pages) return;
+	if (!expect(b))
+		return;
+	if (!expect(b->bm_pages))
+		return;
 	if (number == 0)
 		return;
 	WARN_ON(offset >= b->bm_words);
@@ -832,8 +842,10 @@ void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number,
 
 	end = offset + number;
 
-	ERR_IF(!b) return;
-	ERR_IF(!b->bm_pages) return;
+	if (!expect(b))
+		return;
+	if (!expect(b->bm_pages))
+		return;
 
 	spin_lock_irq(&b->bm_lock);
 	if ((offset >= b->bm_words) ||
@@ -861,8 +873,10 @@ void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number,
 void drbd_bm_set_all(struct drbd_conf *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	ERR_IF(!b) return;
-	ERR_IF(!b->bm_pages) return;
+	if (!expect(b))
+		return;
+	if (!expect(b->bm_pages))
+		return;
 
 	spin_lock_irq(&b->bm_lock);
 	bm_memset(b, 0, 0xff, b->bm_words);
@@ -875,8 +889,10 @@ void drbd_bm_set_all(struct drbd_conf *mdev)
 void drbd_bm_clear_all(struct drbd_conf *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	ERR_IF(!b) return;
-	ERR_IF(!b->bm_pages) return;
+	if (!expect(b))
+		return;
+	if (!expect(b->bm_pages))
+		return;
 
 	spin_lock_irq(&b->bm_lock);
 	bm_memset(b, 0, 0, b->bm_words);
@@ -1209,8 +1225,10 @@ static unsigned long bm_find_next(struct drbd_conf *mdev,
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long i = DRBD_END_OF_BITMAP;
 
-	ERR_IF(!b) return i;
-	ERR_IF(!b->bm_pages) return i;
+	if (!expect(b))
+		return i;
+	if (!expect(b->bm_pages))
+		return i;
 
 	spin_lock_irq(&b->bm_lock);
 	if (BM_DONT_TEST & b->bm_flags)
@@ -1311,8 +1329,10 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
 	struct drbd_bitmap *b = mdev->bitmap;
 	int c = 0;
 
-	ERR_IF(!b) return 1;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 1;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	spin_lock_irqsave(&b->bm_lock, flags);
 	if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags)
@@ -1437,8 +1457,10 @@ int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr)
 	unsigned long *p_addr;
 	int i;
 
-	ERR_IF(!b) return 0;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 0;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	spin_lock_irqsave(&b->bm_lock, flags);
 	if (BM_DONT_TEST & b->bm_flags)
@@ -1472,8 +1494,10 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
 	 * robust in case we screwed up elsewhere, in that case pretend there
 	 * was one dirty bit in the requested area, so we won't try to do a
 	 * local read there (no bitmap probably implies no disk) */
-	ERR_IF(!b) return 1;
-	ERR_IF(!b->bm_pages) return 1;
+	if (!expect(b))
+		return 1;
+	if (!expect(b->bm_pages))
+		return 1;
 
 	spin_lock_irqsave(&b->bm_lock, flags);
 	if (BM_DONT_TEST & b->bm_flags)
@@ -1486,11 +1510,10 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
 				bm_unmap(p_addr);
 			p_addr = bm_map_pidx(b, idx);
 		}
-		ERR_IF (bitnr >= b->bm_bits) {
-			dev_err(DEV, "bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits);
-		} else {
+		if (expect(bitnr < b->bm_bits))
 			c += (0 != test_bit_le(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr));
-		}
+		else
+			dev_err(DEV, "bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits);
 	}
 	if (p_addr)
 		bm_unmap(p_addr);
@@ -1520,8 +1543,10 @@ int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr)
 	unsigned long flags;
 	unsigned long *p_addr, *bm;
 
-	ERR_IF(!b) return 0;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 0;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	spin_lock_irqsave(&b->bm_lock, flags);
 	if (BM_DONT_TEST & b->bm_flags)
@@ -1553,8 +1578,10 @@ unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr)
 	unsigned long weight;
 	unsigned long s, e;
 	int count, i, do_now;
-	ERR_IF(!b) return 0;
-	ERR_IF(!b->bm_pages) return 0;
+	if (!expect(b))
+		return 0;
+	if (!expect(b->bm_pages))
+		return 0;
 
 	spin_lock_irq(&b->bm_lock);
 	if (BM_DONT_SET & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index bb08714..00c9e31 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -102,12 +102,18 @@ struct drbd_conf;
 #define D_ASSERT(exp)	if (!(exp)) \
 	 dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__)
 
-#define ERR_IF(exp) if (({						\
-	int _b = (exp) != 0;						\
-	if (_b) dev_err(DEV, "ASSERT FAILED: %s: (%s) in %s:%d\n",	\
-			__func__, #exp, __FILE__, __LINE__);		\
-	_b;								\
-	}))
+/**
+ * expect  -  Make an assertion
+ *
+ * Unlike the assert macro, this macro returns a boolean result.
+ */
+#define expect(exp) ({								\
+		bool _bool = (exp);						\
+		if (!_bool)							\
+			dev_err(DEV, "ASSERTION %s FAILED in %s\n",		\
+			        #exp, __func__);				\
+		_bool;								\
+		})
 
 /* Defines to control fault insertion */
 enum {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 19176a1..46ba4aa 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1810,7 +1810,7 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 		p == mdev->receiver.task ? &mdev->receiver :
 		p == mdev->worker.task   ? &mdev->worker   :
 		NULL;
-	ERR_IF(thi == NULL)
+	if (!expect(thi != NULL))
 		return;
 	if (!thi->reset_cpu_mask)
 		return;
@@ -1826,8 +1826,10 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
 {
 	int sent, ok;
 
-	ERR_IF(!h) return false;
-	ERR_IF(!size) return false;
+	if (!expect(h))
+		return false;
+	if (!expect(size))
+		return false;
 
 	h->magic   = cpu_to_be32(DRBD_MAGIC);
 	h->command = cpu_to_be16(cmd);
@@ -2300,7 +2302,8 @@ int _drbd_send_bitmap(struct drbd_conf *mdev)
 	struct p_header80 *p;
 	int err;
 
-	ERR_IF(!mdev->bitmap) return false;
+	if (!expect(mdev->bitmap))
+		return false;
 
 	/* maybe we should use some per thread scratch page,
 	 * and allocate that during initial device creation? */
@@ -3255,7 +3258,7 @@ static void drbd_delete_device(unsigned int minor)
 		dev_err(DEV, "open_cnt = %d in %s:%u", mdev->open_cnt,
 				__FILE__ , __LINE__);
 
-	ERR_IF (!list_empty(&mdev->data.work.q)) {
+	if (!expect(list_empty(&mdev->data.work.q))) {
 		struct list_head *lp;
 		list_for_each(lp, &mdev->data.work.q) {
 			dev_err(DEV, "lp = %p\n", lp);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 1840cbb8..51da849 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -751,7 +751,7 @@ static int drbd_check_al_size(struct drbd_conf *mdev)
 	unsigned int in_use;
 	int i;
 
-	ERR_IF(mdev->sync_conf.al_extents < 7)
+	if (!expect(mdev->sync_conf.al_extents >= 7))
 		mdev->sync_conf.al_extents = 127;
 
 	if (mdev->act_log &&
@@ -1804,8 +1804,10 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
 		}
 	}
 
-	ERR_IF (sc.rate < 1) sc.rate = 1;
-	ERR_IF (sc.al_extents < 7) sc.al_extents = 127; /* arbitrary minimum */
+	if (!expect(sc.rate >= 1))
+		sc.rate = 1;
+	if (!expect(sc.al_extents >= 7))
+		sc.al_extents = 127; /* arbitrary minimum */
 #define AL_MAX ((MD_AL_MAX_SIZE-1) * AL_EXTENTS_PT)
 	if (sc.al_extents > AL_MAX) {
 		dev_err(DEV, "sc.al_extents > %d\n", AL_MAX);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1cfcc44..a41b078 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1260,9 +1260,12 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __
 
 	data_size -= dgs;
 
-	ERR_IF(data_size == 0) return NULL;
-	ERR_IF(data_size &  0x1ff) return NULL;
-	ERR_IF(data_size >  DRBD_MAX_BIO_SIZE) return NULL;
+	if (!expect(data_size != 0))
+		return NULL;
+	if (!expect(IS_ALIGNED(data_size, 512)))
+		return NULL;
+	if (!expect(data_size <= DRBD_MAX_BIO_SIZE))
+		return NULL;
 
 	/* even though we trust out peer,
 	 * we sometimes have to double check. */
@@ -3615,7 +3618,8 @@ static int receive_skip(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	while (size > 0) {
 		want = min_t(int, size, sizeof(sink));
 		r = drbd_recv(mdev, sink, want);
-		ERR_IF(r <= 0) break;
+		if (!expect(r > 0))
+			break;
 		size -= r;
 	}
 	return size == 0;
@@ -4493,7 +4497,10 @@ int drbd_asender(struct drbd_thread *thi)
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
-			ERR_IF(!drbd_send_ping(mdev)) goto reconnect;
+			if (!drbd_send_ping(mdev)) {
+				dev_err(DEV, "drbd_send_ping has failed\n");
+				goto reconnect;
+			}
 			mdev->meta.socket->sk->sk_rcvtimeo =
 				mdev->net_conf->ping_timeo*HZ/10;
 			ping_timeout_active = 1;
@@ -4587,7 +4594,7 @@ int drbd_asender(struct drbd_thread *thi)
 				goto disconnect;
 			}
 			expect = cmd->pkt_size;
-			ERR_IF(len != expect-sizeof(struct p_header80))
+			if (!expect(len == expect - sizeof(struct p_header80)))
 				goto reconnect;
 		}
 		if (received == expect) {
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index c2a9285..2e2c065 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1331,7 +1331,8 @@ static int _drbd_may_sync_now(struct drbd_conf *mdev)
 		if (odev->sync_conf.after == -1)
 			return 1;
 		odev = minor_to_mdev(odev->sync_conf.after);
-		ERR_IF(!odev) return 1;
+		if (!expect(odev))
+			return 1;
 		if ((odev->state.conn >= C_SYNC_SOURCE &&
 		     odev->state.conn <= C_PAUSED_SYNC_T) ||
 		    odev->state.aftr_isp || odev->state.peer_isp ||
@@ -1637,7 +1638,7 @@ int drbd_worker(struct drbd_thread *thi)
 		if (intr) {
 			D_ASSERT(intr == -EINTR);
 			flush_signals(current);
-			ERR_IF (get_t_state(thi) == RUNNING)
+			if (!expect(get_t_state(thi) != RUNNING))
 				continue;
 			break;
 		}
@@ -1650,7 +1651,7 @@ int drbd_worker(struct drbd_thread *thi)
 
 		w = NULL;
 		spin_lock_irq(&mdev->data.work.q_lock);
-		ERR_IF(list_empty(&mdev->data.work.q)) {
+		if (!expect(!list_empty(&mdev->data.work.q))) {
 			/* something terribly wrong in our logic.
 			 * we were able to down() the semaphore,
 			 * but the list is empty... doh.
-- 
1.7.4.1


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

* [PATCH 024/118] drbd: Remove some useless paranoia code
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (22 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 023/118] drbd: Replace the ERR_IF macro with an assert-like macro Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 025/118] drbd: Inline function overlaps() is now unused Philipp Reisner
                   ` (95 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

The open_cnt check is an open-coded D_ASSERT() check.

In case the data.work queue is not empty, it does not really help to
know which drbd_work elements remained on that list: they will be freed
immediately afterwards, anyway.

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 46ba4aa..2902f6d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3254,16 +3254,8 @@ static void drbd_delete_device(unsigned int minor)
 		return;
 
 	/* paranoia asserts */
-	if (mdev->open_cnt != 0)
-		dev_err(DEV, "open_cnt = %d in %s:%u", mdev->open_cnt,
-				__FILE__ , __LINE__);
-
-	if (!expect(list_empty(&mdev->data.work.q))) {
-		struct list_head *lp;
-		list_for_each(lp, &mdev->data.work.q) {
-			dev_err(DEV, "lp = %p\n", lp);
-		}
-	};
+	D_ASSERT(mdev->open_cnt == 0);
+	D_ASSERT(list_empty(&mdev->data.work.q));
 	/* end paranoia asserts */
 
 	del_gendisk(mdev->vdisk);
-- 
1.7.4.1


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

* [PATCH 025/118] drbd: Inline function overlaps() is now unused
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (23 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 024/118] drbd: Remove some useless paranoia code Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 026/118] drbd: Interval tree bugfix Philipp Reisner
                   ` (94 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_req.h |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 6dbbe89..9d75647 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -260,11 +260,6 @@ static inline void drbd_req_free(struct drbd_request *req)
 	mempool_free(req, drbd_request_mempool);
 }
 
-static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2)
-{
-	return !((s1 + (l1>>9) <= s2) || (s1 >= s2 + (l2>>9)));
-}
-
 /* Short lived temporary struct on the stack.
  * We could squirrel the error to be returned into
  * bio->bi_size, or similar. But that would be too ugly. */
-- 
1.7.4.1


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

* [PATCH 026/118] drbd: Interval tree bugfix
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (24 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 025/118] drbd: Inline function overlaps() is now unused Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 027/118] idr: idr_for_each_entry() macro Philipp Reisner
                   ` (93 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_interval.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_interval.c b/drivers/block/drbd/drbd_interval.c
index 2511dd9..b77a9bd 100644
--- a/drivers/block/drbd/drbd_interval.c
+++ b/drivers/block/drbd/drbd_interval.c
@@ -58,8 +58,9 @@ drbd_insert_interval(struct rb_root *root, struct drbd_interval *this)
 			new = &(*new)->rb_right;
 		else if (this < here)
 			new = &(*new)->rb_left;
-		else if (this->sector > here->sector)
+		else if (this > here)
 			new = &(*new)->rb_right;
+		else
 			return false;
 	}
 
-- 
1.7.4.1


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

* [PATCH 027/118] idr: idr_for_each_entry() macro
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (25 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 026/118] drbd: Interval tree bugfix Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 028/118] drbd: Minimal struct drbd_tconn Philipp Reisner
                   ` (92 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Inspired by the list_for_each_entry() macro
---
 include/linux/idr.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 255491c..52a9da2 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -152,4 +152,15 @@ void ida_simple_remove(struct ida *ida, unsigned int id);
 
 void __init idr_init_cache(void);
 
+/**
+ * idr_for_each_entry - iterate over an idr's elements of a given type
+ * @idp:     idr handle
+ * @entry:   the type * to use as cursor
+ * @id:      id entry's key
+ */
+#define idr_for_each_entry(idp, entry, id)				\
+	for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
+	     entry != NULL;                                             \
+	     ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
+
 #endif /* __IDR_H__ */
-- 
1.7.4.1


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

* [PATCH 028/118] drbd: Minimal struct drbd_tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (26 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 027/118] idr: idr_for_each_entry() macro Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 029/118] drbd: moved net_conf from mdev to tconn Philipp Reisner
                   ` (91 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Starting to dissolve the network connection from the actual
block devices.

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 |   45 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 00c9e31..c9d70e1 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -94,6 +94,7 @@ extern char usermode_helper[];
 #define UUID_NEW_BM_OFFSET ((u64)0x0001000000000000ULL)
 
 struct drbd_conf;
+struct drbd_tconn;
 
 
 /* to shorten dev_warn(DEV, "msg"); and relatives statements */
@@ -960,7 +961,18 @@ struct fifo_buffer {
 	unsigned int size;
 };
 
+struct drbd_tconn {			/* is a resource from the config file */
+	char *name;			/* Resource name */
+	struct list_head all_tconn;	/* List of all drbd_tconn, prot by global_state_lock */
+	struct drbd_conf *volume0;	/* TODO: Remove me again */
+
+	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
+};
+
 struct drbd_conf {
+	struct drbd_tconn *tconn;
+	int vnr;			/* volume number within the connection */
+
 	/* things that are stored as / read from meta data on disk */
 	unsigned long flags;
 
@@ -1496,6 +1508,9 @@ extern rwlock_t global_state_lock;
 extern struct drbd_conf *drbd_new_device(unsigned int minor);
 extern void drbd_free_mdev(struct drbd_conf *mdev);
 
+struct drbd_tconn *drbd_new_tconn(char *name);
+extern void drbd_free_tconn(struct drbd_tconn *tconn);
+
 extern int proc_details;
 
 /* drbd_req */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 2902f6d..a6ac0c8 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -132,6 +132,7 @@ module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0
  * as member "struct gendisk *vdisk;"
  */
 struct drbd_conf **minor_table;
+struct list_head drbd_tconns;  /* list of struct drbd_tconn */
 
 struct kmem_cache *drbd_request_cache;
 struct kmem_cache *drbd_ee_cache;	/* epoch entries */
@@ -3267,6 +3268,7 @@ static void drbd_delete_device(unsigned int minor)
 		bdput(mdev->this_bdev);
 
 	drbd_free_resources(mdev);
+	drbd_free_tconn(mdev->tconn);
 
 	drbd_release_ee_lists(mdev);
 
@@ -3358,6 +3360,41 @@ out:
 	return r;
 }
 
+struct drbd_tconn *drbd_new_tconn(char *name)
+{
+	struct drbd_tconn *tconn;
+
+	tconn = kzalloc(sizeof(struct drbd_tconn), GFP_KERNEL);
+	if (!tconn)
+		return NULL;
+
+	tconn->name = kstrdup(name, GFP_KERNEL);
+	if (!tconn->name)
+		goto fail;
+
+	write_lock_irq(&global_state_lock);
+	list_add(&tconn->all_tconn, &drbd_tconns);
+	write_unlock_irq(&global_state_lock);
+
+	return tconn;
+
+fail:
+	kfree(tconn->name);
+	kfree(tconn);
+
+	return NULL;
+}
+
+void drbd_free_tconn(struct drbd_tconn *tconn)
+{
+	write_lock_irq(&global_state_lock);
+	list_del(&tconn->all_tconn);
+	write_unlock_irq(&global_state_lock);
+
+	kfree(tconn->name);
+	kfree(tconn);
+}
+
 struct drbd_conf *drbd_new_device(unsigned int minor)
 {
 	struct drbd_conf *mdev;
@@ -3368,9 +3405,14 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
 	if (!mdev)
 		return NULL;
+	mdev->tconn = drbd_new_tconn("dummy");
+	if (!mdev->tconn)
+		goto out_no_tconn;
+
 	if (!zalloc_cpumask_var(&mdev->cpu_mask, GFP_KERNEL))
 		goto out_no_cpumask;
 
+	mdev->tconn->volume0 = mdev;
 	mdev->minor = minor;
 
 	drbd_init_set_defaults(mdev);
@@ -3447,6 +3489,8 @@ out_no_disk:
 out_no_q:
 	free_cpumask_var(mdev->cpu_mask);
 out_no_cpumask:
+	drbd_free_tconn(mdev->tconn);
+out_no_tconn:
 	kfree(mdev);
 	return NULL;
 }
@@ -3526,6 +3570,7 @@ int __init drbd_init(void)
 	}
 
 	rwlock_init(&global_state_lock);
+	INIT_LIST_HEAD(&drbd_tconns);
 
 	printk(KERN_INFO "drbd: initialized. "
 	       "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
-- 
1.7.4.1


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

* [PATCH 029/118] drbd: moved net_conf from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (27 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 028/118] drbd: Minimal struct drbd_tconn Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 030/118] drbd: moved net_cont and net_cnt_wait " Philipp Reisner
                   ` (90 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Besides moving the struct member, everything else is generated by:

sed -i -e 's/mdev->net_conf/mdev->tconn->net_conf/g' \
       -e 's/odev->net_conf/odev->tconn->net_conf/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    7 +-
 drivers/block/drbd/drbd_main.c     |   28 ++++----
 drivers/block/drbd/drbd_nl.c       |   28 ++++----
 drivers/block/drbd/drbd_proc.c     |    4 +-
 drivers/block/drbd/drbd_receiver.c |  124 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_req.c      |   22 +++---
 drivers/block/drbd/drbd_worker.c   |    8 +-
 7 files changed, 110 insertions(+), 111 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c9d70e1..9b41d6f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -977,7 +977,6 @@ struct drbd_conf {
 	unsigned long flags;
 
 	/* configured by drbdsetup */
-	struct net_conf *net_conf; /* protected by get_net_conf() and put_net_conf() */
 	struct syncer_conf sync_conf;
 	struct drbd_backing_dev *ldev __protected_by(local);
 
@@ -2134,10 +2133,10 @@ static inline void put_net_conf(struct drbd_conf *mdev)
 }
 
 /**
- * get_net_conf() - Increase ref count on mdev->net_conf; Returns 0 if nothing there
+ * get_net_conf() - Increase ref count on mdev->tconn->net_conf; Returns 0 if nothing there
  * @mdev:	DRBD device.
  *
- * You have to call put_net_conf() when finished working with mdev->net_conf.
+ * You have to call put_net_conf() when finished working with mdev->tconn->net_conf.
  */
 static inline int get_net_conf(struct drbd_conf *mdev)
 {
@@ -2253,7 +2252,7 @@ static inline int drbd_get_max_buffers(struct drbd_conf *mdev)
 {
 	int mxb = 1000000; /* arbitrary limit on open requests */
 	if (get_net_conf(mdev)) {
-		mxb = mdev->net_conf->max_buffers;
+		mxb = mdev->tconn->net_conf->max_buffers;
 		put_net_conf(mdev);
 	}
 	return mxb;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a6ac0c8..7e88a49 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -693,7 +693,7 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 	}
 
 	if (get_net_conf(mdev)) {
-		if (!mdev->net_conf->two_primaries &&
+		if (!mdev->tconn->net_conf->two_primaries &&
 		    ns.role == R_PRIMARY && ns.peer == R_PRIMARY)
 			rv = SS_TWO_PRIMARIES;
 		put_net_conf(mdev);
@@ -1952,7 +1952,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	size = sizeof(struct p_protocol);
 
 	if (mdev->agreed_pro_version >= 87)
-		size += strlen(mdev->net_conf->integrity_alg) + 1;
+		size += strlen(mdev->tconn->net_conf->integrity_alg) + 1;
 
 	/* we must not recurse into our own queue,
 	 * as that is blocked during handshake */
@@ -1960,16 +1960,16 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	if (p == NULL)
 		return 0;
 
-	p->protocol      = cpu_to_be32(mdev->net_conf->wire_protocol);
-	p->after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
-	p->after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
-	p->after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
-	p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
+	p->protocol      = cpu_to_be32(mdev->tconn->net_conf->wire_protocol);
+	p->after_sb_0p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_0p);
+	p->after_sb_1p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_1p);
+	p->after_sb_2p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_2p);
+	p->two_primaries = cpu_to_be32(mdev->tconn->net_conf->two_primaries);
 
 	cf = 0;
-	if (mdev->net_conf->want_lose)
+	if (mdev->tconn->net_conf->want_lose)
 		cf |= CF_WANT_LOSE;
-	if (mdev->net_conf->dry_run) {
+	if (mdev->tconn->net_conf->dry_run) {
 		if (mdev->agreed_pro_version >= 92)
 			cf |= CF_DRY_RUN;
 		else {
@@ -1981,7 +1981,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	p->conn_flags    = cpu_to_be32(cf);
 
 	if (mdev->agreed_pro_version >= 87)
-		strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
+		strcpy(p->integrity_alg, mdev->tconn->net_conf->integrity_alg);
 
 	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL,
 			   (struct p_header80 *)p, size);
@@ -2002,7 +2002,7 @@ int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags)
 
 	mdev->comm_bm_set = drbd_bm_total_weight(mdev);
 	p.uuid[UI_SIZE] = cpu_to_be64(mdev->comm_bm_set);
-	uuid_flags |= mdev->net_conf->want_lose ? 1 : 0;
+	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);
@@ -2717,7 +2717,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 		 * out ok after sending on this side, but does not fit on the
 		 * receiving side, we sure have detected corruption elsewhere.
 		 */
-		if (mdev->net_conf->wire_protocol == DRBD_PROT_A || dgs)
+		if (mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A || dgs)
 			ok = _drbd_send_bio(mdev, req->master_bio);
 		else
 			ok = _drbd_send_zc_bio(mdev, req->master_bio);
@@ -2843,7 +2843,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 	msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
 
 	if (sock == mdev->data.socket) {
-		mdev->ko_count = mdev->net_conf->ko_count;
+		mdev->ko_count = mdev->tconn->net_conf->ko_count;
 		drbd_update_congested(mdev);
 	}
 	do {
@@ -3073,7 +3073,7 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev)
 		mdev->rs_mark_left[i] = 0;
 		mdev->rs_mark_time[i] = 0;
 	}
-	D_ASSERT(mdev->net_conf == NULL);
+	D_ASSERT(mdev->tconn->net_conf == NULL);
 
 	drbd_set_my_capacity(mdev, 0);
 	if (mdev->bitmap) {
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 51da849..d816c61 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -150,21 +150,21 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
 	snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
 
 	if (get_net_conf(mdev)) {
-		switch (((struct sockaddr *)mdev->net_conf->peer_addr)->sa_family) {
+		switch (((struct sockaddr *)mdev->tconn->net_conf->peer_addr)->sa_family) {
 		case AF_INET6:
 			afs = "ipv6";
 			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI6",
-				 &((struct sockaddr_in6 *)mdev->net_conf->peer_addr)->sin6_addr);
+				 &((struct sockaddr_in6 *)mdev->tconn->net_conf->peer_addr)->sin6_addr);
 			break;
 		case AF_INET:
 			afs = "ipv4";
 			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
-				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
+				 &((struct sockaddr_in *)mdev->tconn->net_conf->peer_addr)->sin_addr);
 			break;
 		default:
 			afs = "ssocks";
 			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
-				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
+				 &((struct sockaddr_in *)mdev->tconn->net_conf->peer_addr)->sin_addr);
 		}
 		snprintf(af, 20, "DRBD_PEER_AF=%s", afs);
 		envp[3]=af;
@@ -379,7 +379,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 		if (rv == SS_TWO_PRIMARIES) {
 			/* Maybe the peer is detected as dead very soon...
 			   retry at most once more in this case. */
-			schedule_timeout_interruptible((mdev->net_conf->ping_timeo+1)*HZ/10);
+			schedule_timeout_interruptible((mdev->tconn->net_conf->ping_timeo+1)*HZ/10);
 			if (try < max_tries)
 				try = max_tries - 1;
 			continue;
@@ -410,7 +410,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 		}
 	} else {
 		if (get_net_conf(mdev)) {
-			mdev->net_conf->want_lose = 0;
+			mdev->tconn->net_conf->want_lose = 0;
 			put_net_conf(mdev);
 		}
 		set_disk_ro(mdev->vdisk, false);
@@ -972,7 +972,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 	}
 
 	if (get_net_conf(mdev)) {
-		int prot = mdev->net_conf->wire_protocol;
+		int prot = mdev->tconn->net_conf->wire_protocol;
 		put_net_conf(mdev);
 		if (nbc->dc.fencing == FP_STONITH && prot == DRBD_PROT_A) {
 			retcode = ERR_STONITH_AND_PROT_A;
@@ -1439,13 +1439,13 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		if (!odev || odev == mdev)
 			continue;
 		if (get_net_conf(odev)) {
-			taken_addr = (struct sockaddr *)&odev->net_conf->my_addr;
-			if (new_conf->my_addr_len == odev->net_conf->my_addr_len &&
+			taken_addr = (struct sockaddr *)&odev->tconn->net_conf->my_addr;
+			if (new_conf->my_addr_len == odev->tconn->net_conf->my_addr_len &&
 			    !memcmp(new_my_addr, taken_addr, new_conf->my_addr_len))
 				retcode = ERR_LOCAL_ADDR;
 
-			taken_addr = (struct sockaddr *)&odev->net_conf->peer_addr;
-			if (new_conf->peer_addr_len == odev->net_conf->peer_addr_len &&
+			taken_addr = (struct sockaddr *)&odev->tconn->net_conf->peer_addr;
+			if (new_conf->peer_addr_len == odev->tconn->net_conf->peer_addr_len &&
 			    !memcmp(new_peer_addr, taken_addr, new_conf->peer_addr_len))
 				retcode = ERR_PEER_ADDR;
 
@@ -1522,12 +1522,12 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 
 	drbd_flush_workqueue(mdev);
 	spin_lock_irq(&mdev->req_lock);
-	if (mdev->net_conf != NULL) {
+	if (mdev->tconn->net_conf != NULL) {
 		retcode = ERR_NET_CONFIGURED;
 		spin_unlock_irq(&mdev->req_lock);
 		goto fail;
 	}
-	mdev->net_conf = new_conf;
+	mdev->tconn->net_conf = new_conf;
 
 	mdev->send_cnt = 0;
 	mdev->recv_cnt = 0;
@@ -2051,7 +2051,7 @@ static int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 	}
 
 	if (get_net_conf(mdev)) {
-		tl = net_conf_to_tags(mdev, mdev->net_conf, tl);
+		tl = net_conf_to_tags(mdev, mdev->tconn->net_conf, tl);
 		put_net_conf(mdev);
 	}
 	tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl);
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index 2959cdf..4e53cb3 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -254,8 +254,8 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
 			   drbd_role_str(mdev->state.peer),
 			   drbd_disk_str(mdev->state.disk),
 			   drbd_disk_str(mdev->state.pdsk),
-			   (mdev->net_conf == NULL ? ' ' :
-			    (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')),
+			   (mdev->tconn->net_conf == NULL ? ' ' :
+			    (mdev->tconn->net_conf->wire_protocol - DRBD_PROT_A+'A')),
 			   is_susp(mdev->state) ? 's' : 'r',
 			   mdev->state.aftr_isp ? 'a' : '-',
 			   mdev->state.peer_isp ? 'p' : '-',
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index a41b078..e5e7dd1 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -237,7 +237,7 @@ static struct page *drbd_pp_alloc(struct drbd_conf *mdev, unsigned number, bool
 
 	/* Yes, we may run up to @number over max_buffers. If we
 	 * follow it strictly, the admin will get it wrong anyways. */
-	if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers)
+	if (atomic_read(&mdev->pp_in_use) < mdev->tconn->net_conf->max_buffers)
 		page = drbd_pp_first_pages_or_try_alloc(mdev, number);
 
 	while (page == NULL) {
@@ -245,7 +245,7 @@ static struct page *drbd_pp_alloc(struct drbd_conf *mdev, unsigned number, bool
 
 		drbd_kick_lo_and_reclaim_net(mdev);
 
-		if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) {
+		if (atomic_read(&mdev->pp_in_use) < mdev->tconn->net_conf->max_buffers) {
 			page = drbd_pp_first_pages_or_try_alloc(mdev, number);
 			if (page)
 				break;
@@ -582,7 +582,7 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 		return NULL;
 
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family,
+	err = sock_create_kern(((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family,
 		SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (err < 0) {
 		sock = NULL;
@@ -590,9 +590,9 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	}
 
 	sock->sk->sk_rcvtimeo =
-	sock->sk->sk_sndtimeo =  mdev->net_conf->try_connect_int*HZ;
-	drbd_setbufsize(sock, mdev->net_conf->sndbuf_size,
-			mdev->net_conf->rcvbuf_size);
+	sock->sk->sk_sndtimeo =  mdev->tconn->net_conf->try_connect_int*HZ;
+	drbd_setbufsize(sock, mdev->tconn->net_conf->sndbuf_size,
+			mdev->tconn->net_conf->rcvbuf_size);
 
        /* explicitly bind to the configured IP as source IP
 	*  for the outgoing connections.
@@ -601,9 +601,9 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	* Make sure to use 0 as port number, so linux selects
 	*  a free one dynamically.
 	*/
-	memcpy(&src_in6, mdev->net_conf->my_addr,
-	       min_t(int, mdev->net_conf->my_addr_len, sizeof(src_in6)));
-	if (((struct sockaddr *)mdev->net_conf->my_addr)->sa_family == AF_INET6)
+	memcpy(&src_in6, mdev->tconn->net_conf->my_addr,
+	       min_t(int, mdev->tconn->net_conf->my_addr_len, sizeof(src_in6)));
+	if (((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family == AF_INET6)
 		src_in6.sin6_port = 0;
 	else
 		((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */
@@ -611,7 +611,7 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	what = "bind before connect";
 	err = sock->ops->bind(sock,
 			      (struct sockaddr *) &src_in6,
-			      mdev->net_conf->my_addr_len);
+			      mdev->tconn->net_conf->my_addr_len);
 	if (err < 0)
 		goto out;
 
@@ -620,8 +620,8 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	disconnect_on_error = 0;
 	what = "connect";
 	err = sock->ops->connect(sock,
-				 (struct sockaddr *)mdev->net_conf->peer_addr,
-				 mdev->net_conf->peer_addr_len, 0);
+				 (struct sockaddr *)mdev->tconn->net_conf->peer_addr,
+				 mdev->tconn->net_conf->peer_addr_len, 0);
 
 out:
 	if (err < 0) {
@@ -658,26 +658,26 @@ static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev)
 		return NULL;
 
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family,
+	err = sock_create_kern(((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family,
 		SOCK_STREAM, IPPROTO_TCP, &s_listen);
 	if (err) {
 		s_listen = NULL;
 		goto out;
 	}
 
-	timeo = mdev->net_conf->try_connect_int * HZ;
+	timeo = mdev->tconn->net_conf->try_connect_int * HZ;
 	timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */
 
 	s_listen->sk->sk_reuse    = 1; /* SO_REUSEADDR */
 	s_listen->sk->sk_rcvtimeo = timeo;
 	s_listen->sk->sk_sndtimeo = timeo;
-	drbd_setbufsize(s_listen, mdev->net_conf->sndbuf_size,
-			mdev->net_conf->rcvbuf_size);
+	drbd_setbufsize(s_listen, mdev->tconn->net_conf->sndbuf_size,
+			mdev->tconn->net_conf->rcvbuf_size);
 
 	what = "bind before listen";
 	err = s_listen->ops->bind(s_listen,
-			      (struct sockaddr *) mdev->net_conf->my_addr,
-			      mdev->net_conf->my_addr_len);
+			      (struct sockaddr *) mdev->tconn->net_conf->my_addr,
+			      mdev->tconn->net_conf->my_addr_len);
 	if (err < 0)
 		goto out;
 
@@ -791,7 +791,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 		}
 
 		if (sock && msock) {
-			schedule_timeout_interruptible(mdev->net_conf->ping_timeo*HZ/10);
+			schedule_timeout_interruptible(mdev->tconn->net_conf->ping_timeo*HZ/10);
 			ok = drbd_socket_okay(mdev, &sock);
 			ok = drbd_socket_okay(mdev, &msock) && ok;
 			if (ok)
@@ -855,15 +855,15 @@ retry:
 	msock->sk->sk_priority = TC_PRIO_INTERACTIVE;
 
 	/* NOT YET ...
-	 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
+	 * sock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
 	 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 	 * first set it to the P_HAND_SHAKE timeout,
 	 * which we set to 4x the configured ping_timeout. */
 	sock->sk->sk_sndtimeo =
-	sock->sk->sk_rcvtimeo = mdev->net_conf->ping_timeo*4*HZ/10;
+	sock->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_timeo*4*HZ/10;
 
-	msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
-	msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+	msock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
+	msock->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
 
 	/* we don't want delays.
 	 * we use TCP_CORK where appropriate, though */
@@ -895,7 +895,7 @@ retry:
 	if (drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS)
 		return 0;
 
-	sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
+	sock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
 	sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 
 	atomic_set(&mdev->packet_seq, 0);
@@ -1555,7 +1555,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	sector_t sector = e->i.sector;
 	int ok = 1, pcmd;
 
-	if (mdev->net_conf->wire_protocol == DRBD_PROT_C) {
+	if (mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C) {
 		if (likely((e->flags & EE_WAS_ERROR) == 0)) {
 			pcmd = (mdev->state.conn >= C_SYNC_SOURCE &&
 				mdev->state.conn <= C_PAUSED_SYNC_T &&
@@ -1573,7 +1573,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	}
 	/* we delete from the conflict detection hash _after_ we sent out the
 	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
-	if (mdev->net_conf->two_primaries) {
+	if (mdev->tconn->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->req_lock);
 		D_ASSERT(!drbd_interval_empty(&e->i));
 		drbd_remove_interval(&mdev->epoch_entries, &e->i);
@@ -1592,7 +1592,7 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
 	int ok = 1;
 
-	D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+	D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
 
 	spin_lock_irq(&mdev->req_lock);
@@ -1717,7 +1717,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	spin_unlock(&mdev->epoch_lock);
 
 	/* I'm the receiver, I do hold a net_cnt reference. */
-	if (!mdev->net_conf->two_primaries) {
+	if (!mdev->tconn->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->req_lock);
 	} else {
 		/* don't get the req_lock yet,
@@ -1727,7 +1727,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		DEFINE_WAIT(wait);
 		int first;
 
-		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 
 		/* conflict detection and handling:
 		 * 1. wait on the sequence number,
@@ -1845,7 +1845,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	list_add(&e->w.list, &mdev->active_ee);
 	spin_unlock_irq(&mdev->req_lock);
 
-	switch (mdev->net_conf->wire_protocol) {
+	switch (mdev->tconn->net_conf->wire_protocol) {
 	case DRBD_PROT_C:
 		inc_unacked(mdev);
 		/* corresponding dec_unacked() in e_end_block()
@@ -2153,7 +2153,7 @@ static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
 	ch_peer = mdev->p_uuid[UI_SIZE];
 	ch_self = mdev->comm_bm_set;
 
-	switch (mdev->net_conf->after_sb_0p) {
+	switch (mdev->tconn->net_conf->after_sb_0p) {
 	case ASB_CONSENSUS:
 	case ASB_DISCARD_SECONDARY:
 	case ASB_CALL_HELPER:
@@ -2192,7 +2192,7 @@ static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
 			if (ch_peer == 0) { rv =  1; break; }
 			if (ch_self == 0) { rv = -1; break; }
 		}
-		if (mdev->net_conf->after_sb_0p == ASB_DISCARD_ZERO_CHG)
+		if (mdev->tconn->net_conf->after_sb_0p == ASB_DISCARD_ZERO_CHG)
 			break;
 	case ASB_DISCARD_LEAST_CHG:
 		if	(ch_self < ch_peer)
@@ -2218,7 +2218,7 @@ static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local)
 {
 	int hg, rv = -100;
 
-	switch (mdev->net_conf->after_sb_1p) {
+	switch (mdev->tconn->net_conf->after_sb_1p) {
 	case ASB_DISCARD_YOUNGER_PRI:
 	case ASB_DISCARD_OLDER_PRI:
 	case ASB_DISCARD_LEAST_CHG:
@@ -2267,7 +2267,7 @@ static int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local)
 {
 	int hg, rv = -100;
 
-	switch (mdev->net_conf->after_sb_2p) {
+	switch (mdev->tconn->net_conf->after_sb_2p) {
 	case ASB_DISCARD_YOUNGER_PRI:
 	case ASB_DISCARD_OLDER_PRI:
 	case ASB_DISCARD_LEAST_CHG:
@@ -2558,7 +2558,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
 	if (abs(hg) == 100)
 		drbd_khelper(mdev, "initial-split-brain");
 
-	if (hg == 100 || (hg == -100 && mdev->net_conf->always_asbp)) {
+	if (hg == 100 || (hg == -100 && mdev->tconn->net_conf->always_asbp)) {
 		int pcount = (mdev->state.role == R_PRIMARY)
 			   + (peer_role == R_PRIMARY);
 		int forced = (hg == -100);
@@ -2587,9 +2587,9 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
 	}
 
 	if (hg == -100) {
-		if (mdev->net_conf->want_lose && !(mdev->p_uuid[UI_FLAGS]&1))
+		if (mdev->tconn->net_conf->want_lose && !(mdev->p_uuid[UI_FLAGS]&1))
 			hg = -1;
-		if (!mdev->net_conf->want_lose && (mdev->p_uuid[UI_FLAGS]&1))
+		if (!mdev->tconn->net_conf->want_lose && (mdev->p_uuid[UI_FLAGS]&1))
 			hg = 1;
 
 		if (abs(hg) < 100)
@@ -2615,7 +2615,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
 
 	if (hg < 0 && /* by intention we do not use mydisk here. */
 	    mdev->state.role == R_PRIMARY && mdev->state.disk >= D_CONSISTENT) {
-		switch (mdev->net_conf->rr_conflict) {
+		switch (mdev->tconn->net_conf->rr_conflict) {
 		case ASB_CALL_HELPER:
 			drbd_khelper(mdev, "pri-lost");
 			/* fall through */
@@ -2628,7 +2628,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
 		}
 	}
 
-	if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
+	if (mdev->tconn->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
 		if (hg == 0)
 			dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
 		else
@@ -2701,38 +2701,38 @@ static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsig
 	if (cf & CF_DRY_RUN)
 		set_bit(CONN_DRY_RUN, &mdev->flags);
 
-	if (p_proto != mdev->net_conf->wire_protocol) {
+	if (p_proto != mdev->tconn->net_conf->wire_protocol) {
 		dev_err(DEV, "incompatible communication protocols\n");
 		goto disconnect;
 	}
 
-	if (cmp_after_sb(p_after_sb_0p, mdev->net_conf->after_sb_0p)) {
+	if (cmp_after_sb(p_after_sb_0p, mdev->tconn->net_conf->after_sb_0p)) {
 		dev_err(DEV, "incompatible after-sb-0pri settings\n");
 		goto disconnect;
 	}
 
-	if (cmp_after_sb(p_after_sb_1p, mdev->net_conf->after_sb_1p)) {
+	if (cmp_after_sb(p_after_sb_1p, mdev->tconn->net_conf->after_sb_1p)) {
 		dev_err(DEV, "incompatible after-sb-1pri settings\n");
 		goto disconnect;
 	}
 
-	if (cmp_after_sb(p_after_sb_2p, mdev->net_conf->after_sb_2p)) {
+	if (cmp_after_sb(p_after_sb_2p, mdev->tconn->net_conf->after_sb_2p)) {
 		dev_err(DEV, "incompatible after-sb-2pri settings\n");
 		goto disconnect;
 	}
 
-	if (p_want_lose && mdev->net_conf->want_lose) {
+	if (p_want_lose && mdev->tconn->net_conf->want_lose) {
 		dev_err(DEV, "both sides have the 'want_lose' flag set\n");
 		goto disconnect;
 	}
 
-	if (p_two_primaries != mdev->net_conf->two_primaries) {
+	if (p_two_primaries != mdev->tconn->net_conf->two_primaries) {
 		dev_err(DEV, "incompatible setting of the two-primaries options\n");
 		goto disconnect;
 	}
 
 	if (mdev->agreed_pro_version >= 87) {
-		unsigned char *my_alg = mdev->net_conf->integrity_alg;
+		unsigned char *my_alg = mdev->tconn->net_conf->integrity_alg;
 
 		if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size)
 			return false;
@@ -3312,7 +3312,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		}
 	}
 
-	mdev->net_conf->want_lose = 0;
+	mdev->tconn->net_conf->want_lose = 0;
 
 	drbd_md_sync(mdev); /* update connected indicator, la_size, ... */
 
@@ -3844,8 +3844,8 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 		crypto_free_hash(mdev->cram_hmac_tfm);
 		mdev->cram_hmac_tfm = NULL;
 
-		kfree(mdev->net_conf);
-		mdev->net_conf = NULL;
+		kfree(mdev->tconn->net_conf);
+		mdev->tconn->net_conf = NULL;
 		drbd_request_state(mdev, NS(conn, C_STANDALONE));
 	}
 
@@ -4005,7 +4005,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	char *response = NULL;
 	char *right_response = NULL;
 	char *peers_ch = NULL;
-	unsigned int key_len = strlen(mdev->net_conf->shared_secret);
+	unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
 	unsigned int resp_size;
 	struct hash_desc desc;
 	enum drbd_packets cmd;
@@ -4016,7 +4016,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	desc.flags = 0;
 
 	rv = crypto_hash_setkey(mdev->cram_hmac_tfm,
-				(u8 *)mdev->net_conf->shared_secret, key_len);
+				(u8 *)mdev->tconn->net_conf->shared_secret, key_len);
 	if (rv) {
 		dev_err(DEV, "crypto_hash_setkey() failed with %d\n", rv);
 		rv = -1;
@@ -4130,7 +4130,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 
 	if (rv)
 		dev_info(DEV, "Peer authenticated using %d bytes of '%s' HMAC\n",
-		     resp_size, mdev->net_conf->cram_hmac_alg);
+		     resp_size, mdev->tconn->net_conf->cram_hmac_alg);
 	else
 		rv = -1;
 
@@ -4207,7 +4207,7 @@ static int got_Ping(struct drbd_conf *mdev, struct p_header80 *h)
 static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h)
 {
 	/* restore idle timeout */
-	mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+	mdev->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
 	if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
 		wake_up(&mdev->misc_wait);
 
@@ -4275,19 +4275,19 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 	}
 	switch (be16_to_cpu(h->command)) {
 	case P_RS_WRITE_ACK:
-		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 		what = WRITE_ACKED_BY_PEER_AND_SIS;
 		break;
 	case P_WRITE_ACK:
-		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 		what = WRITE_ACKED_BY_PEER;
 		break;
 	case P_RECV_ACK:
-		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_B);
+		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_B);
 		what = RECV_ACKED_BY_PEER;
 		break;
 	case P_DISCARD_ACK:
-		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 		what = CONFLICT_DISCARDED_BY_PEER;
 		break;
 	default:
@@ -4305,8 +4305,8 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	struct p_block_ack *p = (struct p_block_ack *)h;
 	sector_t sector = be64_to_cpu(p->sector);
 	int size = be32_to_cpu(p->blksize);
-	bool missing_ok = mdev->net_conf->wire_protocol == DRBD_PROT_A ||
-			  mdev->net_conf->wire_protocol == DRBD_PROT_B;
+	bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A ||
+			  mdev->tconn->net_conf->wire_protocol == DRBD_PROT_B;
 	bool found;
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
@@ -4502,13 +4502,13 @@ int drbd_asender(struct drbd_thread *thi)
 				goto reconnect;
 			}
 			mdev->meta.socket->sk->sk_rcvtimeo =
-				mdev->net_conf->ping_timeo*HZ/10;
+				mdev->tconn->net_conf->ping_timeo*HZ/10;
 			ping_timeout_active = 1;
 		}
 
 		/* conditionally cork;
 		 * it may hurt latency if we cork without much to send */
-		if (!mdev->net_conf->no_cork &&
+		if (!mdev->tconn->net_conf->no_cork &&
 			3 < atomic_read(&mdev->unacked_cnt))
 			drbd_tcp_cork(mdev->meta.socket);
 		while (1) {
@@ -4528,7 +4528,7 @@ int drbd_asender(struct drbd_thread *thi)
 				break;
 		}
 		/* but unconditionally uncork unless disabled */
-		if (!mdev->net_conf->no_cork)
+		if (!mdev->tconn->net_conf->no_cork)
 			drbd_tcp_uncork(mdev->meta.socket);
 
 		/* short circuit, recv_msg would return EINTR anyways. */
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index b3b1d4e..2b2662d 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -528,7 +528,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		drbd_queue_work(&mdev->data.work, &req->w);
 
 		/* close the epoch, in case it outgrew the limit */
-		if (mdev->newest_tle->n_writes >= mdev->net_conf->max_epoch_size)
+		if (mdev->newest_tle->n_writes >= mdev->tconn->net_conf->max_epoch_size)
 			queue_barrier(mdev);
 
 		break;
@@ -558,7 +558,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			atomic_add(req->i.size >> 9, &mdev->ap_in_flight);
 
 		if (bio_data_dir(req->master_bio) == WRITE &&
-		    mdev->net_conf->wire_protocol == DRBD_PROT_A) {
+		    mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A) {
 			/* this is what is dangerous about protocol A:
 			 * pretend it was successfully written on the peer. */
 			if (req->rq_state & RQ_NET_PENDING) {
@@ -697,8 +697,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		}
 		if ((req->rq_state & RQ_NET_MASK) != 0) {
 			req->rq_state |= RQ_NET_DONE;
-			if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
-				atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
+			if (mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A)
+				atomic_sub(req->i.size>>9, &mdev->ap_in_flight);
 		}
 		_req_may_be_done(req, m); /* Allowed while state.susp */
 		break;
@@ -951,16 +951,16 @@ allocate_barrier:
 		_req_mod(req, QUEUE_FOR_SEND_OOS);
 
 	if (remote &&
-	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
+	    mdev->tconn->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
 		int congested = 0;
 
-		if (mdev->net_conf->cong_fill &&
-		    atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
+		if (mdev->tconn->net_conf->cong_fill &&
+		    atomic_read(&mdev->ap_in_flight) >= mdev->tconn->net_conf->cong_fill) {
 			dev_info(DEV, "Congestion-fill threshold reached\n");
 			congested = 1;
 		}
 
-		if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
+		if (mdev->act_log->used >= mdev->tconn->net_conf->cong_extents) {
 			dev_info(DEV, "Congestion-extents threshold reached\n");
 			congested = 1;
 		}
@@ -968,9 +968,9 @@ allocate_barrier:
 		if (congested) {
 			queue_barrier(mdev); /* last barrier, after mirrored writes */
 
-			if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
+			if (mdev->tconn->net_conf->on_congestion == OC_PULL_AHEAD)
 				_drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
-			else  /*mdev->net_conf->on_congestion == OC_DISCONNECT */
+			else  /*mdev->tconn->net_conf->on_congestion == OC_DISCONNECT */
 				_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
 		}
 	}
@@ -1182,7 +1182,7 @@ void request_timer_fn(unsigned long data)
 	unsigned long et = 0; /* effective timeout = ko_count * timeout */
 
 	if (get_net_conf(mdev)) {
-		et = mdev->net_conf->timeout*HZ/10 * mdev->net_conf->ko_count;
+		et = mdev->tconn->net_conf->timeout*HZ/10 * mdev->tconn->net_conf->ko_count;
 		put_net_conf(mdev);
 	}
 	if (!et || mdev->state.conn < C_WF_REPORT_PARAMS)
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 2e2c065..d8c6181 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1590,8 +1590,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 			 * the race considerably, but does not solve it. */
 			if (side == C_SYNC_SOURCE)
 				schedule_timeout_interruptible(
-					mdev->net_conf->ping_int * HZ +
-					mdev->net_conf->ping_timeo*HZ/9);
+					mdev->tconn->net_conf->ping_int * HZ +
+					mdev->tconn->net_conf->ping_timeo*HZ/9);
 			drbd_resync_finished(mdev);
 		}
 
@@ -1623,14 +1623,14 @@ int drbd_worker(struct drbd_thread *thi)
 
 		if (down_trylock(&mdev->data.work.s)) {
 			mutex_lock(&mdev->data.mutex);
-			if (mdev->data.socket && !mdev->net_conf->no_cork)
+			if (mdev->data.socket && !mdev->tconn->net_conf->no_cork)
 				drbd_tcp_uncork(mdev->data.socket);
 			mutex_unlock(&mdev->data.mutex);
 
 			intr = down_interruptible(&mdev->data.work.s);
 
 			mutex_lock(&mdev->data.mutex);
-			if (mdev->data.socket  && !mdev->net_conf->no_cork)
+			if (mdev->data.socket  && !mdev->tconn->net_conf->no_cork)
 				drbd_tcp_cork(mdev->data.socket);
 			mutex_unlock(&mdev->data.mutex);
 		}
-- 
1.7.4.1


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

* [PATCH 030/118] drbd: moved net_cont and net_cnt_wait from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (28 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 029/118] drbd: moved net_conf from mdev to tconn Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 031/118] drbd: moved data and meta " Philipp Reisner
                   ` (89 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Patch partly generated by:

sed -i -e 's/get_net_conf(mdev)/get_net_conf(mdev->tconn)/g' \
       -e 's/put_net_conf(mdev)/put_net_conf(mdev->tconn)/g' \
       -e 's/get_net_conf(odev)/get_net_conf(odev->tconn)/g' \
       -e 's/put_net_conf(odev)/put_net_conf(odev->tconn)/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   23 ++++++++++++-----------
 drivers/block/drbd/drbd_main.c     |    9 +++++----
 drivers/block/drbd/drbd_nl.c       |   20 ++++++++++----------
 drivers/block/drbd/drbd_receiver.c |   14 +++++++-------
 drivers/block/drbd/drbd_req.c      |   10 +++++-----
 5 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9b41d6f..a464642 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -967,6 +967,8 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct drbd_conf *volume0;	/* TODO: Remove me again */
 
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
+	atomic_t net_cnt;		/* Users of net_conf */
+	wait_queue_head_t net_cnt_wait;
 };
 
 struct drbd_conf {
@@ -1012,7 +1014,6 @@ struct drbd_conf {
 	union drbd_state state;
 	wait_queue_head_t misc_wait;
 	wait_queue_head_t state_wait;  /* upon each state change. */
-	wait_queue_head_t net_cnt_wait;
 	unsigned int send_cnt;
 	unsigned int recv_cnt;
 	unsigned int read_cnt;
@@ -1024,7 +1025,7 @@ struct drbd_conf {
 	atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
 	atomic_t unacked_cnt;	 /* Need to send replys for */
 	atomic_t local_cnt;	 /* Waiting for local completion */
-	atomic_t net_cnt;	 /* Users of net_conf */
+
 	spinlock_t req_lock;
 	struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */
 	struct drbd_tl_epoch *newest_tle;
@@ -2126,10 +2127,10 @@ static inline void inc_unacked(struct drbd_conf *mdev)
 	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0)
 
 
-static inline void put_net_conf(struct drbd_conf *mdev)
+static inline void put_net_conf(struct drbd_tconn *tconn)
 {
-	if (atomic_dec_and_test(&mdev->net_cnt))
-		wake_up(&mdev->net_cnt_wait);
+	if (atomic_dec_and_test(&tconn->net_cnt))
+		wake_up(&tconn->net_cnt_wait);
 }
 
 /**
@@ -2138,14 +2139,14 @@ static inline void put_net_conf(struct drbd_conf *mdev)
  *
  * You have to call put_net_conf() when finished working with mdev->tconn->net_conf.
  */
-static inline int get_net_conf(struct drbd_conf *mdev)
+static inline int get_net_conf(struct drbd_tconn *tconn)
 {
 	int have_net_conf;
 
-	atomic_inc(&mdev->net_cnt);
-	have_net_conf = mdev->state.conn >= C_UNCONNECTED;
+	atomic_inc(&tconn->net_cnt);
+	have_net_conf = tconn->volume0->state.conn >= C_UNCONNECTED;
 	if (!have_net_conf)
-		put_net_conf(mdev);
+		put_net_conf(tconn);
 	return have_net_conf;
 }
 
@@ -2251,9 +2252,9 @@ static inline void drbd_get_syncer_progress(struct drbd_conf *mdev,
 static inline int drbd_get_max_buffers(struct drbd_conf *mdev)
 {
 	int mxb = 1000000; /* arbitrary limit on open requests */
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		mxb = mdev->tconn->net_conf->max_buffers;
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 	}
 	return mxb;
 }
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7e88a49..9a77a9b 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -692,11 +692,11 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 		put_ldev(mdev);
 	}
 
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		if (!mdev->tconn->net_conf->two_primaries &&
 		    ns.role == R_PRIMARY && ns.peer == R_PRIMARY)
 			rv = SS_TWO_PRIMARIES;
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 	}
 
 	if (rv <= 0)
@@ -2972,7 +2972,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	atomic_set(&mdev->rs_pending_cnt, 0);
 	atomic_set(&mdev->unacked_cnt, 0);
 	atomic_set(&mdev->local_cnt, 0);
-	atomic_set(&mdev->net_cnt, 0);
 	atomic_set(&mdev->packet_seq, 0);
 	atomic_set(&mdev->pp_in_use, 0);
 	atomic_set(&mdev->pp_in_use_by_net, 0);
@@ -3031,7 +3030,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 
 	init_waitqueue_head(&mdev->misc_wait);
 	init_waitqueue_head(&mdev->state_wait);
-	init_waitqueue_head(&mdev->net_cnt_wait);
 	init_waitqueue_head(&mdev->ee_wait);
 	init_waitqueue_head(&mdev->al_wait);
 	init_waitqueue_head(&mdev->seq_wait);
@@ -3372,6 +3370,9 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 	if (!tconn->name)
 		goto fail;
 
+	atomic_set(&tconn->net_cnt, 0);
+	init_waitqueue_head(&tconn->net_cnt_wait);
+
 	write_lock_irq(&global_state_lock);
 	list_add(&tconn->all_tconn, &drbd_tconns);
 	write_unlock_irq(&global_state_lock);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index d816c61..a936d61 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -149,7 +149,7 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
 
 	snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
 
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		switch (((struct sockaddr *)mdev->tconn->net_conf->peer_addr)->sa_family) {
 		case AF_INET6:
 			afs = "ipv6";
@@ -169,7 +169,7 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
 		snprintf(af, 20, "DRBD_PEER_AF=%s", afs);
 		envp[3]=af;
 		envp[4]=ad;
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 	}
 
 	/* The helper may take some time.
@@ -409,9 +409,9 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 			put_ldev(mdev);
 		}
 	} else {
-		if (get_net_conf(mdev)) {
+		if (get_net_conf(mdev->tconn)) {
 			mdev->tconn->net_conf->want_lose = 0;
-			put_net_conf(mdev);
+			put_net_conf(mdev->tconn);
 		}
 		set_disk_ro(mdev->vdisk, false);
 		if (get_ldev(mdev)) {
@@ -971,9 +971,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 		goto fail;
 	}
 
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		int prot = mdev->tconn->net_conf->wire_protocol;
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 		if (nbc->dc.fencing == FP_STONITH && prot == DRBD_PROT_A) {
 			retcode = ERR_STONITH_AND_PROT_A;
 			goto fail;
@@ -1438,7 +1438,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		odev = minor_to_mdev(i);
 		if (!odev || odev == mdev)
 			continue;
-		if (get_net_conf(odev)) {
+		if (get_net_conf(odev->tconn)) {
 			taken_addr = (struct sockaddr *)&odev->tconn->net_conf->my_addr;
 			if (new_conf->my_addr_len == odev->tconn->net_conf->my_addr_len &&
 			    !memcmp(new_my_addr, taken_addr, new_conf->my_addr_len))
@@ -1449,7 +1449,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 			    !memcmp(new_peer_addr, taken_addr, new_conf->peer_addr_len))
 				retcode = ERR_PEER_ADDR;
 
-			put_net_conf(odev);
+			put_net_conf(odev->tconn);
 			if (retcode != NO_ERROR)
 				goto fail;
 		}
@@ -2050,9 +2050,9 @@ static int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 		put_ldev(mdev);
 	}
 
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		tl = net_conf_to_tags(mdev, mdev->tconn->net_conf, tl);
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 	}
 	tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e5e7dd1..8a01f27 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -578,7 +578,7 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	int err;
 	int disconnect_on_error = 1;
 
-	if (!get_net_conf(mdev))
+	if (!get_net_conf(mdev->tconn))
 		return NULL;
 
 	what = "sock_create_kern";
@@ -644,7 +644,7 @@ out:
 		if (disconnect_on_error)
 			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
 	}
-	put_net_conf(mdev);
+	put_net_conf(mdev->tconn);
 	return sock;
 }
 
@@ -654,7 +654,7 @@ static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev)
 	struct socket *s_estab = NULL, *s_listen;
 	const char *what;
 
-	if (!get_net_conf(mdev))
+	if (!get_net_conf(mdev->tconn))
 		return NULL;
 
 	what = "sock_create_kern";
@@ -692,7 +692,7 @@ out:
 			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
 		}
 	}
-	put_net_conf(mdev);
+	put_net_conf(mdev->tconn);
 
 	return s_estab;
 }
@@ -3839,7 +3839,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	spin_unlock_irq(&mdev->req_lock);
 
 	if (os.conn == C_DISCONNECTING) {
-		wait_event(mdev->net_cnt_wait, atomic_read(&mdev->net_cnt) == 0);
+		wait_event(mdev->tconn->net_cnt_wait, atomic_read(&mdev->tconn->net_cnt) == 0);
 
 		crypto_free_hash(mdev->cram_hmac_tfm);
 		mdev->cram_hmac_tfm = NULL;
@@ -4166,9 +4166,9 @@ int drbdd_init(struct drbd_thread *thi)
 	} while (h == 0);
 
 	if (h > 0) {
-		if (get_net_conf(mdev)) {
+		if (get_net_conf(mdev->tconn)) {
 			drbdd(mdev);
-			put_net_conf(mdev);
+			put_net_conf(mdev->tconn);
 		}
 	}
 
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 2b2662d..8f1e7db 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -323,7 +323,7 @@ static int _req_conflicts(struct drbd_request *req)
 
 	D_ASSERT(drbd_interval_empty(&req->i));
 
-	if (!get_net_conf(mdev))
+	if (!get_net_conf(mdev->tconn))
 		return 0;
 
 	i = drbd_find_overlap(&mdev->write_requests, sector, size);
@@ -359,11 +359,11 @@ static int _req_conflicts(struct drbd_request *req)
 
 	/* this is like it should be, and what we expected.
 	 * our users do behave after all... */
-	put_net_conf(mdev);
+	put_net_conf(mdev->tconn);
 	return 0;
 
 out_conflict:
-	put_net_conf(mdev);
+	put_net_conf(mdev->tconn);
 	return 1;
 }
 
@@ -1181,9 +1181,9 @@ void request_timer_fn(unsigned long data)
 	struct list_head *le;
 	unsigned long et = 0; /* effective timeout = ko_count * timeout */
 
-	if (get_net_conf(mdev)) {
+	if (get_net_conf(mdev->tconn)) {
 		et = mdev->tconn->net_conf->timeout*HZ/10 * mdev->tconn->net_conf->ko_count;
-		put_net_conf(mdev);
+		put_net_conf(mdev->tconn);
 	}
 	if (!et || mdev->state.conn < C_WF_REPORT_PARAMS)
 		return; /* Recurring timer stopped */
-- 
1.7.4.1


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

* [PATCH 031/118] drbd: moved data and meta from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (29 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 030/118] drbd: moved net_cont and net_cnt_wait " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 032/118] drbd: moved receiver, worker and asender " Philipp Reisner
                   ` (88 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Patch mostly:

sed -i -e 's/mdev->data/mdev->tconn->data/g' \
       -e 's/mdev->meta/mdev->tconn->meta/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_actlog.c   |    4 +-
 drivers/block/drbd/drbd_int.h      |   17 +++---
 drivers/block/drbd/drbd_main.c     |  122 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_receiver.c |   82 ++++++++++++------------
 drivers/block/drbd/drbd_req.c      |   12 ++--
 drivers/block/drbd/drbd_worker.c   |   66 ++++++++++----------
 6 files changed, 152 insertions(+), 151 deletions(-)

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 9284b10..7943177 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -228,7 +228,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector)
 		al_work.enr = enr;
 		al_work.old_enr = al_ext->lc_number;
 		al_work.w.cb = w_al_write_transaction;
-		drbd_queue_work_front(&mdev->data.work, &al_work.w);
+		drbd_queue_work_front(&mdev->tconn->data.work, &al_work.w);
 		wait_for_completion(&al_work.event);
 
 		mdev->al_writ_cnt++;
@@ -717,7 +717,7 @@ static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector,
 			if (udw) {
 				udw->enr = ext->lce.lc_number;
 				udw->w.cb = w_update_odbm;
-				drbd_queue_work_front(&mdev->data.work, &udw->w);
+				drbd_queue_work_front(&mdev->tconn->data.work, &udw->w);
 			} else {
 				dev_warn(DEV, "Could not kmalloc an udw\n");
 			}
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index a464642..015ec05 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -969,6 +969,9 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
 	atomic_t net_cnt;		/* Users of net_conf */
 	wait_queue_head_t net_cnt_wait;
+
+	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
+	struct drbd_socket meta;	/* ping/ack (metadata) packets */
 };
 
 struct drbd_conf {
@@ -987,8 +990,6 @@ struct drbd_conf {
 	struct block_device *this_bdev;
 	struct gendisk	    *vdisk;
 
-	struct drbd_socket data; /* data/barrier/cstate/parameter packets */
-	struct drbd_socket meta; /* ping/ack (metadata) packets */
 	int agreed_pro_version;  /* actually used protocol version */
 	unsigned long last_received; /* in jiffies, either socket */
 	unsigned int ko_count;
@@ -1167,11 +1168,11 @@ static inline unsigned int mdev_to_minor(struct drbd_conf *mdev)
  */
 static inline int drbd_get_data_sock(struct drbd_conf *mdev)
 {
-	mutex_lock(&mdev->data.mutex);
+	mutex_lock(&mdev->tconn->data.mutex);
 	/* drbd_disconnect() could have called drbd_free_sock()
 	 * while we were waiting in down()... */
-	if (unlikely(mdev->data.socket == NULL)) {
-		mutex_unlock(&mdev->data.mutex);
+	if (unlikely(mdev->tconn->data.socket == NULL)) {
+		mutex_unlock(&mdev->tconn->data.mutex);
 		return 0;
 	}
 	return 1;
@@ -1179,7 +1180,7 @@ static inline int drbd_get_data_sock(struct drbd_conf *mdev)
 
 static inline void drbd_put_data_sock(struct drbd_conf *mdev)
 {
-	mutex_unlock(&mdev->data.mutex);
+	mutex_unlock(&mdev->tconn->data.mutex);
 }
 
 /*
@@ -2399,7 +2400,7 @@ static inline void dec_ap_bio(struct drbd_conf *mdev)
 		wake_up(&mdev->misc_wait);
 	if (ap_bio == 0 && test_bit(BITMAP_IO, &mdev->flags)) {
 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags))
-			drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w);
+			drbd_queue_work(&mdev->tconn->data.work, &mdev->bm_io_work.w);
 	}
 }
 
@@ -2439,7 +2440,7 @@ static inline void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq)
 
 static inline void drbd_update_congested(struct drbd_conf *mdev)
 {
-	struct sock *sk = mdev->data.socket->sk;
+	struct sock *sk = mdev->tconn->data.socket->sk;
 	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
 		set_bit(NET_CONGESTED, &mdev->flags);
 }
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9a77a9b..84e40fb 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -371,7 +371,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 					set_bit(CREATE_BARRIER, &mdev->flags);
 				}
 
-				drbd_queue_work(&mdev->data.work, &b->w);
+				drbd_queue_work(&mdev->tconn->data.work, &b->w);
 			}
 			pn = &b->next;
 		} else {
@@ -1251,7 +1251,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 		ascw->flags = flags;
 		ascw->w.cb = w_after_state_ch;
 		ascw->done = done;
-		drbd_queue_work(&mdev->data.work, &ascw->w);
+		drbd_queue_work(&mdev->tconn->data.work, &ascw->w);
 	} else {
 		dev_warn(DEV, "Could not kmalloc an ascw\n");
 	}
@@ -1855,11 +1855,11 @@ int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 	struct socket *sock;
 
 	if (use_data_socket) {
-		mutex_lock(&mdev->data.mutex);
-		sock = mdev->data.socket;
+		mutex_lock(&mdev->tconn->data.mutex);
+		sock = mdev->tconn->data.socket;
 	} else {
-		mutex_lock(&mdev->meta.mutex);
-		sock = mdev->meta.socket;
+		mutex_lock(&mdev->tconn->meta.mutex);
+		sock = mdev->tconn->meta.socket;
 	}
 
 	/* drbd_disconnect() could have called drbd_free_sock()
@@ -1868,9 +1868,9 @@ int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 		ok = _drbd_send_cmd(mdev, sock, cmd, h, size, 0);
 
 	if (use_data_socket)
-		mutex_unlock(&mdev->data.mutex);
+		mutex_unlock(&mdev->tconn->data.mutex);
 	else
-		mutex_unlock(&mdev->meta.mutex);
+		mutex_unlock(&mdev->tconn->meta.mutex);
 	return ok;
 }
 
@@ -1888,9 +1888,9 @@ int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
 		return 0;
 
 	ok = (sizeof(h) ==
-		drbd_send(mdev, mdev->data.socket, &h, sizeof(h), 0));
+		drbd_send(mdev, mdev->tconn->data.socket, &h, sizeof(h), 0));
 	ok = ok && (size ==
-		drbd_send(mdev, mdev->data.socket, data, size, 0));
+		drbd_send(mdev, mdev->tconn->data.socket, data, size, 0));
 
 	drbd_put_data_sock(mdev);
 
@@ -1913,13 +1913,13 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 	/* used from admin command context and receiver/worker context.
 	 * to avoid kmalloc, grab the socket right here,
 	 * then use the pre-allocated sbuf there */
-	mutex_lock(&mdev->data.mutex);
-	sock = mdev->data.socket;
+	mutex_lock(&mdev->tconn->data.mutex);
+	sock = mdev->tconn->data.socket;
 
 	if (likely(sock != NULL)) {
 		enum drbd_packets cmd = apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
 
-		p = &mdev->data.sbuf.rs_param_95;
+		p = &mdev->tconn->data.sbuf.rs_param_95;
 
 		/* initialize verify_alg and csums_alg */
 		memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
@@ -1939,7 +1939,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 	} else
 		rv = 0; /* not ok */
 
-	mutex_unlock(&mdev->data.mutex);
+	mutex_unlock(&mdev->tconn->data.mutex);
 
 	return rv;
 }
@@ -2106,17 +2106,17 @@ int drbd_send_state(struct drbd_conf *mdev)
 	 * of a cluster wide state change on another thread */
 	drbd_state_lock(mdev);
 
-	mutex_lock(&mdev->data.mutex);
+	mutex_lock(&mdev->tconn->data.mutex);
 
 	p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */
-	sock = mdev->data.socket;
+	sock = mdev->tconn->data.socket;
 
 	if (likely(sock != NULL)) {
 		ok = _drbd_send_cmd(mdev, sock, P_STATE,
 				    (struct p_header80 *)&p, sizeof(p), 0);
 	}
 
-	mutex_unlock(&mdev->data.mutex);
+	mutex_unlock(&mdev->tconn->data.mutex);
 
 	drbd_state_unlock(mdev);
 	return ok;
@@ -2260,7 +2260,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
 
 	if (len) {
 		DCBP_set_code(p, RLE_VLI_Bits);
-		ok = _drbd_send_cmd(mdev, mdev->data.socket, P_COMPRESSED_BITMAP, h,
+		ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_COMPRESSED_BITMAP, h,
 			sizeof(*p) + len, 0);
 
 		c->packets[0]++;
@@ -2275,7 +2275,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
 		len = num_words * sizeof(long);
 		if (len)
 			drbd_bm_get_lel(mdev, c->word_offset, num_words, (unsigned long*)h->payload);
-		ok = _drbd_send_cmd(mdev, mdev->data.socket, P_BITMAP,
+		ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_BITMAP,
 				   h, sizeof(struct p_header80) + len, 0);
 		c->word_offset += num_words;
 		c->bit_offset = c->word_offset * BITS_PER_LONG;
@@ -2391,7 +2391,7 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
 	p.blksize  = blksize;
 	p.seq_num  = cpu_to_be32(atomic_add_return(1, &mdev->packet_seq));
 
-	if (!mdev->meta.socket || mdev->state.conn < C_CONNECTED)
+	if (!mdev->tconn->meta.socket || mdev->state.conn < C_CONNECTED)
 		return false;
 	ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd,
 				(struct p_header80 *)&p, sizeof(p));
@@ -2473,12 +2473,12 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev,
 	p.head.command = cpu_to_be16(cmd);
 	p.head.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + digest_size);
 
-	mutex_lock(&mdev->data.mutex);
+	mutex_lock(&mdev->tconn->data.mutex);
 
-	ok = (sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, sizeof(p), 0));
-	ok = ok && (digest_size == drbd_send(mdev, mdev->data.socket, digest, digest_size, 0));
+	ok = (sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), 0));
+	ok = ok && (digest_size == drbd_send(mdev, mdev->tconn->data.socket, digest, digest_size, 0));
 
-	mutex_unlock(&mdev->data.mutex);
+	mutex_unlock(&mdev->tconn->data.mutex);
 
 	return ok;
 }
@@ -2506,7 +2506,7 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 	int drop_it;
 	/* long elapsed = (long)(jiffies - mdev->last_received); */
 
-	drop_it =   mdev->meta.socket == sock
+	drop_it =   mdev->tconn->meta.socket == sock
 		|| !mdev->asender.task
 		|| get_t_state(&mdev->asender) != RUNNING
 		|| mdev->state.conn < C_CONNECTED;
@@ -2548,7 +2548,7 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
 		   int offset, size_t size, unsigned msg_flags)
 {
-	int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, msg_flags);
+	int sent = drbd_send(mdev, mdev->tconn->data.socket, kmap(page) + offset, size, msg_flags);
 	kunmap(page);
 	if (sent == size)
 		mdev->send_cnt += size>>9;
@@ -2575,12 +2575,12 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
 	drbd_update_congested(mdev);
 	set_fs(KERNEL_DS);
 	do {
-		sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page,
+		sent = mdev->tconn->data.socket->ops->sendpage(mdev->tconn->data.socket, page,
 							offset, len,
 							msg_flags);
 		if (sent == -EAGAIN) {
 			if (we_should_drop_the_connection(mdev,
-							  mdev->data.socket))
+							  mdev->tconn->data.socket))
 				break;
 			else
 				continue;
@@ -2699,11 +2699,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	p.dp_flags = cpu_to_be32(dp_flags);
 	set_bit(UNPLUG_REMOTE, &mdev->flags);
 	ok = (sizeof(p) ==
-		drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
+		drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
 	if (ok && dgs) {
 		dgb = mdev->int_dig_out;
 		drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb);
-		ok = dgs == drbd_send(mdev, mdev->data.socket, dgb, dgs, 0);
+		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok) {
 		/* For protocol A, we have to memcpy the payload into
@@ -2781,11 +2781,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 	if (!drbd_get_data_sock(mdev))
 		return 0;
 
-	ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
+	ok = sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
 	if (ok && dgs) {
 		dgb = mdev->int_dig_out;
 		drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb);
-		ok = dgs == drbd_send(mdev, mdev->data.socket, dgb, dgs, 0);
+		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok)
 		ok = _drbd_send_zc_ee(mdev, e);
@@ -2842,7 +2842,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 	msg.msg_controllen = 0;
 	msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
 
-	if (sock == mdev->data.socket) {
+	if (sock == mdev->tconn->data.socket) {
 		mdev->ko_count = mdev->tconn->net_conf->ko_count;
 		drbd_update_congested(mdev);
 	}
@@ -2875,13 +2875,13 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 		iov.iov_len  -= rv;
 	} while (sent < size);
 
-	if (sock == mdev->data.socket)
+	if (sock == mdev->tconn->data.socket)
 		clear_bit(NET_CONGESTED, &mdev->flags);
 
 	if (rv <= 0) {
 		if (rv != -EAGAIN) {
 			dev_err(DEV, "%s_sendmsg returned %d\n",
-			    sock == mdev->meta.socket ? "msock" : "sock",
+			    sock == mdev->tconn->meta.socket ? "msock" : "sock",
 			    rv);
 			drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE));
 		} else
@@ -2980,14 +2980,14 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	atomic_set(&mdev->ap_in_flight, 0);
 
 	mutex_init(&mdev->md_io_mutex);
-	mutex_init(&mdev->data.mutex);
-	mutex_init(&mdev->meta.mutex);
-	sema_init(&mdev->data.work.s, 0);
-	sema_init(&mdev->meta.work.s, 0);
+	mutex_init(&mdev->tconn->data.mutex);
+	mutex_init(&mdev->tconn->meta.mutex);
+	sema_init(&mdev->tconn->data.work.s, 0);
+	sema_init(&mdev->tconn->meta.work.s, 0);
 	mutex_init(&mdev->state_mutex);
 
-	spin_lock_init(&mdev->data.work.q_lock);
-	spin_lock_init(&mdev->meta.work.q_lock);
+	spin_lock_init(&mdev->tconn->data.work.q_lock);
+	spin_lock_init(&mdev->tconn->meta.work.q_lock);
 
 	spin_lock_init(&mdev->al_lock);
 	spin_lock_init(&mdev->req_lock);
@@ -3000,8 +3000,8 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	INIT_LIST_HEAD(&mdev->read_ee);
 	INIT_LIST_HEAD(&mdev->net_ee);
 	INIT_LIST_HEAD(&mdev->resync_reads);
-	INIT_LIST_HEAD(&mdev->data.work.q);
-	INIT_LIST_HEAD(&mdev->meta.work.q);
+	INIT_LIST_HEAD(&mdev->tconn->data.work.q);
+	INIT_LIST_HEAD(&mdev->tconn->meta.work.q);
 	INIT_LIST_HEAD(&mdev->resync_work.list);
 	INIT_LIST_HEAD(&mdev->unplug_work.list);
 	INIT_LIST_HEAD(&mdev->go_diskless.list);
@@ -3093,8 +3093,8 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev)
 	D_ASSERT(list_empty(&mdev->read_ee));
 	D_ASSERT(list_empty(&mdev->net_ee));
 	D_ASSERT(list_empty(&mdev->resync_reads));
-	D_ASSERT(list_empty(&mdev->data.work.q));
-	D_ASSERT(list_empty(&mdev->meta.work.q));
+	D_ASSERT(list_empty(&mdev->tconn->data.work.q));
+	D_ASSERT(list_empty(&mdev->tconn->meta.work.q));
 	D_ASSERT(list_empty(&mdev->resync_work.list));
 	D_ASSERT(list_empty(&mdev->unplug_work.list));
 	D_ASSERT(list_empty(&mdev->go_diskless.list));
@@ -3254,7 +3254,7 @@ static void drbd_delete_device(unsigned int minor)
 
 	/* paranoia asserts */
 	D_ASSERT(mdev->open_cnt == 0);
-	D_ASSERT(list_empty(&mdev->data.work.q));
+	D_ASSERT(list_empty(&mdev->tconn->data.work.q));
 	/* end paranoia asserts */
 
 	del_gendisk(mdev->vdisk);
@@ -3606,19 +3606,19 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
 
 void drbd_free_sock(struct drbd_conf *mdev)
 {
-	if (mdev->data.socket) {
-		mutex_lock(&mdev->data.mutex);
-		kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
-		sock_release(mdev->data.socket);
-		mdev->data.socket = NULL;
-		mutex_unlock(&mdev->data.mutex);
+	if (mdev->tconn->data.socket) {
+		mutex_lock(&mdev->tconn->data.mutex);
+		kernel_sock_shutdown(mdev->tconn->data.socket, SHUT_RDWR);
+		sock_release(mdev->tconn->data.socket);
+		mdev->tconn->data.socket = NULL;
+		mutex_unlock(&mdev->tconn->data.mutex);
 	}
-	if (mdev->meta.socket) {
-		mutex_lock(&mdev->meta.mutex);
-		kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
-		sock_release(mdev->meta.socket);
-		mdev->meta.socket = NULL;
-		mutex_unlock(&mdev->meta.mutex);
+	if (mdev->tconn->meta.socket) {
+		mutex_lock(&mdev->tconn->meta.mutex);
+		kernel_sock_shutdown(mdev->tconn->meta.socket, SHUT_RDWR);
+		sock_release(mdev->tconn->meta.socket);
+		mdev->tconn->meta.socket = NULL;
+		mutex_unlock(&mdev->tconn->meta.mutex);
 	}
 }
 
@@ -4012,7 +4012,7 @@ void drbd_go_diskless(struct drbd_conf *mdev)
 {
 	D_ASSERT(mdev->state.disk == D_FAILED);
 	if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
-		drbd_queue_work(&mdev->data.work, &mdev->go_diskless);
+		drbd_queue_work(&mdev->tconn->data.work, &mdev->go_diskless);
 }
 
 /**
@@ -4050,7 +4050,7 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
 	set_bit(BITMAP_IO, &mdev->flags);
 	if (atomic_read(&mdev->ap_bio_cnt) == 0) {
 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags))
-			drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w);
+			drbd_queue_work(&mdev->tconn->data.work, &mdev->bm_io_work.w);
 	}
 	spin_unlock_irq(&mdev->req_lock);
 }
@@ -4108,7 +4108,7 @@ static void md_sync_timer_fn(unsigned long data)
 {
 	struct drbd_conf *mdev = (struct drbd_conf *) data;
 
-	drbd_queue_work_front(&mdev->data.work, &mdev->md_sync_work);
+	drbd_queue_work_front(&mdev->tconn->data.work, &mdev->md_sync_work);
 }
 
 static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 8a01f27..2636bcc 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -516,7 +516,7 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
 	set_fs(KERNEL_DS);
 
 	for (;;) {
-		rv = sock_recvmsg(mdev->data.socket, &msg, size, msg.msg_flags);
+		rv = sock_recvmsg(mdev->tconn->data.socket, &msg, size, msg.msg_flags);
 		if (rv == size)
 			break;
 
@@ -700,14 +700,14 @@ out:
 static int drbd_send_fp(struct drbd_conf *mdev,
 	struct socket *sock, enum drbd_packets cmd)
 {
-	struct p_header80 *h = &mdev->data.sbuf.header.h80;
+	struct p_header80 *h = &mdev->tconn->data.sbuf.header.h80;
 
 	return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0);
 }
 
 static enum drbd_packets drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock)
 {
-	struct p_header80 *h = &mdev->data.rbuf.header.h80;
+	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
 	int rr;
 
 	rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0);
@@ -755,7 +755,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 	struct socket *s, *sock, *msock;
 	int try, h, ok;
 
-	D_ASSERT(!mdev->data.socket);
+	D_ASSERT(!mdev->tconn->data.socket);
 
 	if (drbd_request_state(mdev, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
 		return -2;
@@ -870,8 +870,8 @@ retry:
 	drbd_tcp_nodelay(sock);
 	drbd_tcp_nodelay(msock);
 
-	mdev->data.socket = sock;
-	mdev->meta.socket = msock;
+	mdev->tconn->data.socket = sock;
+	mdev->tconn->meta.socket = msock;
 	mdev->last_received = jiffies;
 
 	D_ASSERT(mdev->asender.task == NULL);
@@ -925,7 +925,7 @@ out_release_sockets:
 
 static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
 {
-	union p_header *h = &mdev->data.rbuf.header;
+	union p_header *h = &mdev->tconn->data.rbuf.header;
 	int r;
 
 	r = drbd_recv(mdev, h, sizeof(*h));
@@ -1163,7 +1163,7 @@ fail:
 static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
 	int rv;
-	struct p_barrier *p = &mdev->data.rbuf.barrier;
+	struct p_barrier *p = &mdev->tconn->data.rbuf.barrier;
 	struct drbd_epoch *epoch;
 
 	inc_unacked(mdev);
@@ -1494,7 +1494,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	struct drbd_request *req;
 	sector_t sector;
 	int ok;
-	struct p_data *p = &mdev->data.rbuf.data;
+	struct p_data *p = &mdev->tconn->data.rbuf.data;
 
 	sector = be64_to_cpu(p->sector);
 
@@ -1522,7 +1522,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packets cmd, un
 {
 	sector_t sector;
 	int ok;
-	struct p_data *p = &mdev->data.rbuf.data;
+	struct p_data *p = &mdev->tconn->data.rbuf.data;
 
 	sector = be64_to_cpu(p->sector);
 	D_ASSERT(p->block_id == ID_SYNCER);
@@ -1675,7 +1675,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 {
 	sector_t sector;
 	struct drbd_epoch_entry *e;
-	struct p_data *p = &mdev->data.rbuf.data;
+	struct p_data *p = &mdev->tconn->data.rbuf.data;
 	int rw = WRITE;
 	u32 dp_flags;
 
@@ -1964,7 +1964,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un
 	struct digest_info *di = NULL;
 	int size, verb;
 	unsigned int fault_type;
-	struct p_block_req *p =	&mdev->data.rbuf.block_req;
+	struct p_block_req *p =	&mdev->tconn->data.rbuf.block_req;
 
 	sector = be64_to_cpu(p->sector);
 	size   = be32_to_cpu(p->blksize);
@@ -2683,7 +2683,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
 
 static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_protocol *p = &mdev->data.rbuf.protocol;
+	struct p_protocol *p = &mdev->tconn->data.rbuf.protocol;
 	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] = "";
@@ -2783,7 +2783,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
 static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int packet_size)
 {
 	int ok = true;
-	struct p_rs_param_95 *p = &mdev->data.rbuf.rs_param_95;
+	struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95;
 	unsigned int header_size, data_size, exp_max_sz;
 	struct crypto_hash *verify_tfm = NULL;
 	struct crypto_hash *csums_tfm = NULL;
@@ -2946,7 +2946,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
 
 static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_sizes *p = &mdev->data.rbuf.sizes;
+	struct p_sizes *p = &mdev->tconn->data.rbuf.sizes;
 	enum determine_dev_size dd = unchanged;
 	sector_t p_size, p_usize, my_usize;
 	int ldsc = 0; /* local disk size changed */
@@ -3049,7 +3049,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_uuids *p = &mdev->data.rbuf.uuids;
+	struct p_uuids *p = &mdev->tconn->data.rbuf.uuids;
 	u64 *p_uuid;
 	int i, updated_uuids = 0;
 
@@ -3143,7 +3143,7 @@ static union drbd_state convert_state(union drbd_state ps)
 
 static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_req_state *p = &mdev->data.rbuf.req_state;
+	struct p_req_state *p = &mdev->tconn->data.rbuf.req_state;
 	union drbd_state mask, val;
 	enum drbd_state_rv rv;
 
@@ -3169,7 +3169,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 
 static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_state *p = &mdev->data.rbuf.state;
+	struct p_state *p = &mdev->tconn->data.rbuf.state;
 	union drbd_state os, ns, peer_state;
 	enum drbd_disk_state real_peer_disk;
 	enum chg_state_flags cs_flags;
@@ -3321,7 +3321,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_rs_uuid *p = &mdev->data.rbuf.rs_uuid;
+	struct p_rs_uuid *p = &mdev->tconn->data.rbuf.rs_uuid;
 
 	wait_event(mdev->misc_wait,
 		   mdev->state.conn == C_WF_SYNC_UUID ||
@@ -3520,7 +3520,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
 	void *buffer;
 	int err;
 	int ok = false;
-	struct p_header80 *h = &mdev->data.rbuf.header.h80;
+	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
 
 	drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
 	/* you are supposed to send additional out-of-sync information
@@ -3629,14 +3629,14 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, u
 {
 	/* Make sure we've acked all the TCP data associated
 	 * with the data requests being unplugged */
-	drbd_tcp_quickack(mdev->data.socket);
+	drbd_tcp_quickack(mdev->tconn->data.socket);
 
 	return true;
 }
 
 static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-	struct p_block_desc *p = &mdev->data.rbuf.block_desc;
+	struct p_block_desc *p = &mdev->tconn->data.rbuf.block_desc;
 
 	switch (mdev->state.conn) {
 	case C_WF_SYNC_UUID:
@@ -3690,15 +3690,15 @@ static struct data_cmd drbd_cmd_handler[] = {
 };
 
 /* All handler functions that expect a sub-header get that sub-heder in
-   mdev->data.rbuf.header.head.payload.
+   mdev->tconn->data.rbuf.header.head.payload.
 
-   Usually in mdev->data.rbuf.header.head the callback can find the usual
+   Usually in mdev->tconn->data.rbuf.header.head the callback can find the usual
    p_header, but they may not rely on that. Since there is also p_header95 !
  */
 
 static void drbdd(struct drbd_conf *mdev)
 {
-	union p_header *header = &mdev->data.rbuf.header;
+	union p_header *header = &mdev->tconn->data.rbuf.header;
 	unsigned int packet_size;
 	enum drbd_packets cmd;
 	size_t shs; /* sub header size */
@@ -3753,7 +3753,7 @@ void drbd_flush_workqueue(struct drbd_conf *mdev)
 
 	barr.w.cb = w_prev_work_done;
 	init_completion(&barr.done);
-	drbd_queue_work(&mdev->data.work, &barr.w);
+	drbd_queue_work(&mdev->tconn->data.work, &barr.w);
 	wait_for_completion(&barr.done);
 }
 
@@ -3892,25 +3892,25 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 static int drbd_send_handshake(struct drbd_conf *mdev)
 {
 	/* ASSERT current == mdev->receiver ... */
-	struct p_handshake *p = &mdev->data.sbuf.handshake;
+	struct p_handshake *p = &mdev->tconn->data.sbuf.handshake;
 	int ok;
 
-	if (mutex_lock_interruptible(&mdev->data.mutex)) {
+	if (mutex_lock_interruptible(&mdev->tconn->data.mutex)) {
 		dev_err(DEV, "interrupted during initial handshake\n");
 		return 0; /* interrupted. not ok. */
 	}
 
-	if (mdev->data.socket == NULL) {
-		mutex_unlock(&mdev->data.mutex);
+	if (mdev->tconn->data.socket == NULL) {
+		mutex_unlock(&mdev->tconn->data.mutex);
 		return 0;
 	}
 
 	memset(p, 0, sizeof(*p));
 	p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
 	p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
-	ok = _drbd_send_cmd( mdev, mdev->data.socket, P_HAND_SHAKE,
+	ok = _drbd_send_cmd( mdev, mdev->tconn->data.socket, P_HAND_SHAKE,
 			     (struct p_header80 *)p, sizeof(*p), 0 );
-	mutex_unlock(&mdev->data.mutex);
+	mutex_unlock(&mdev->tconn->data.mutex);
 	return ok;
 }
 
@@ -3924,7 +3924,7 @@ static int drbd_send_handshake(struct drbd_conf *mdev)
 static int drbd_do_handshake(struct drbd_conf *mdev)
 {
 	/* ASSERT current == mdev->receiver ... */
-	struct p_handshake *p = &mdev->data.rbuf.handshake;
+	struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
 	const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
 	unsigned int length;
 	enum drbd_packets cmd;
@@ -4207,7 +4207,7 @@ static int got_Ping(struct drbd_conf *mdev, struct p_header80 *h)
 static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h)
 {
 	/* restore idle timeout */
-	mdev->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
+	mdev->tconn->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
 	if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
 		wake_up(&mdev->misc_wait);
 
@@ -4427,7 +4427,7 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h)
 		w = kmalloc(sizeof(*w), GFP_NOIO);
 		if (w) {
 			w->cb = w_ov_finished;
-			drbd_queue_work_front(&mdev->data.work, w);
+			drbd_queue_work_front(&mdev->tconn->data.work, w);
 		} else {
 			dev_err(DEV, "kmalloc(w) failed.");
 			ov_oos_print(mdev);
@@ -4479,7 +4479,7 @@ static struct asender_cmd *get_asender_cmd(int cmd)
 int drbd_asender(struct drbd_thread *thi)
 {
 	struct drbd_conf *mdev = thi->mdev;
-	struct p_header80 *h = &mdev->meta.rbuf.header.h80;
+	struct p_header80 *h = &mdev->tconn->meta.rbuf.header.h80;
 	struct asender_cmd *cmd = NULL;
 
 	int rv, len;
@@ -4501,7 +4501,7 @@ int drbd_asender(struct drbd_thread *thi)
 				dev_err(DEV, "drbd_send_ping has failed\n");
 				goto reconnect;
 			}
-			mdev->meta.socket->sk->sk_rcvtimeo =
+			mdev->tconn->meta.socket->sk->sk_rcvtimeo =
 				mdev->tconn->net_conf->ping_timeo*HZ/10;
 			ping_timeout_active = 1;
 		}
@@ -4510,7 +4510,7 @@ int drbd_asender(struct drbd_thread *thi)
 		 * it may hurt latency if we cork without much to send */
 		if (!mdev->tconn->net_conf->no_cork &&
 			3 < atomic_read(&mdev->unacked_cnt))
-			drbd_tcp_cork(mdev->meta.socket);
+			drbd_tcp_cork(mdev->tconn->meta.socket);
 		while (1) {
 			clear_bit(SIGNAL_ASENDER, &mdev->flags);
 			flush_signals(current);
@@ -4529,13 +4529,13 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 		/* but unconditionally uncork unless disabled */
 		if (!mdev->tconn->net_conf->no_cork)
-			drbd_tcp_uncork(mdev->meta.socket);
+			drbd_tcp_uncork(mdev->tconn->meta.socket);
 
 		/* short circuit, recv_msg would return EINTR anyways. */
 		if (signal_pending(current))
 			continue;
 
-		rv = drbd_recv_short(mdev, mdev->meta.socket,
+		rv = drbd_recv_short(mdev, mdev->tconn->meta.socket,
 				     buf, expect-received, 0);
 		clear_bit(SIGNAL_ASENDER, &mdev->flags);
 
@@ -4561,7 +4561,7 @@ int drbd_asender(struct drbd_thread *thi)
 			/* If the data socket received something meanwhile,
 			 * that is good enough: peer is still alive. */
 			if (time_after(mdev->last_received,
-				jiffies - mdev->meta.socket->sk->sk_rcvtimeo))
+				jiffies - mdev->tconn->meta.socket->sk->sk_rcvtimeo))
 				continue;
 			if (ping_timeout_active) {
 				dev_err(DEV, "PingAck did not arrive in time.\n");
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8f1e7db..ac43e44 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -127,7 +127,7 @@ static void queue_barrier(struct drbd_conf *mdev)
 	 * dec_ap_pending will be done in got_BarrierAck
 	 * or (on connection loss) in tl_clear.  */
 	inc_ap_pending(mdev);
-	drbd_queue_work(&mdev->data.work, &b->w);
+	drbd_queue_work(&mdev->tconn->data.work, &b->w);
 	set_bit(CREATE_BARRIER, &mdev->flags);
 }
 
@@ -483,7 +483,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		req->w.cb = (req->rq_state & RQ_LOCAL_MASK)
 			? w_read_retry_remote
 			: w_send_read_req;
-		drbd_queue_work(&mdev->data.work, &req->w);
+		drbd_queue_work(&mdev->tconn->data.work, &req->w);
 		break;
 
 	case QUEUE_FOR_NET_WRITE:
@@ -525,7 +525,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
 		req->rq_state |= RQ_NET_QUEUED;
 		req->w.cb =  w_send_dblock;
-		drbd_queue_work(&mdev->data.work, &req->w);
+		drbd_queue_work(&mdev->tconn->data.work, &req->w);
 
 		/* close the epoch, in case it outgrew the limit */
 		if (mdev->newest_tle->n_writes >= mdev->tconn->net_conf->max_epoch_size)
@@ -536,7 +536,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 	case QUEUE_FOR_SEND_OOS:
 		req->rq_state |= RQ_NET_QUEUED;
 		req->w.cb =  w_send_oos;
-		drbd_queue_work(&mdev->data.work, &req->w);
+		drbd_queue_work(&mdev->tconn->data.work, &req->w);
 		break;
 
 	case OOS_HANDED_TO_NETWORK:
@@ -667,7 +667,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 
 		get_ldev(mdev);
 		req->w.cb = w_restart_disk_io;
-		drbd_queue_work(&mdev->data.work, &req->w);
+		drbd_queue_work(&mdev->tconn->data.work, &req->w);
 		break;
 
 	case RESEND:
@@ -677,7 +677,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		   We ensure that the peer was not rebooted */
 		if (!(req->rq_state & RQ_NET_OK)) {
 			if (req->w.cb) {
-				drbd_queue_work(&mdev->data.work, &req->w);
+				drbd_queue_work(&mdev->tconn->data.work, &req->w);
 				rv = req->rq_state & RQ_WRITE ? MR_WRITE : MR_READ;
 			}
 			break;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index d8c6181..9b1e2ba 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -94,7 +94,7 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
 		__drbd_chk_io_error(mdev, false);
 	spin_unlock_irqrestore(&mdev->req_lock, flags);
 
-	drbd_queue_work(&mdev->data.work, &e->w);
+	drbd_queue_work(&mdev->tconn->data.work, &e->w);
 	put_ldev(mdev);
 }
 
@@ -400,7 +400,7 @@ void resync_timer_fn(unsigned long data)
 	struct drbd_conf *mdev = (struct drbd_conf *) data;
 
 	if (list_empty(&mdev->resync_work.list))
-		drbd_queue_work(&mdev->data.work, &mdev->resync_work);
+		drbd_queue_work(&mdev->tconn->data.work, &mdev->resync_work);
 }
 
 static void fifo_set(struct fifo_buffer *fb, int value)
@@ -538,15 +538,15 @@ static int w_make_resync_request(struct drbd_conf *mdev,
 
 	for (i = 0; i < number; i++) {
 		/* Stop generating RS requests, when half of the send buffer is filled */
-		mutex_lock(&mdev->data.mutex);
-		if (mdev->data.socket) {
-			queued = mdev->data.socket->sk->sk_wmem_queued;
-			sndbuf = mdev->data.socket->sk->sk_sndbuf;
+		mutex_lock(&mdev->tconn->data.mutex);
+		if (mdev->tconn->data.socket) {
+			queued = mdev->tconn->data.socket->sk->sk_wmem_queued;
+			sndbuf = mdev->tconn->data.socket->sk->sk_sndbuf;
 		} else {
 			queued = 1;
 			sndbuf = 0;
 		}
-		mutex_unlock(&mdev->data.mutex);
+		mutex_unlock(&mdev->tconn->data.mutex);
 		if (queued > sndbuf / 2)
 			goto requeue;
 
@@ -710,7 +710,7 @@ void start_resync_timer_fn(unsigned long data)
 {
 	struct drbd_conf *mdev = (struct drbd_conf *) data;
 
-	drbd_queue_work(&mdev->data.work, &mdev->start_resync_work);
+	drbd_queue_work(&mdev->tconn->data.work, &mdev->start_resync_work);
 }
 
 int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
@@ -775,7 +775,7 @@ int drbd_resync_finished(struct drbd_conf *mdev)
 		w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC);
 		if (w) {
 			w->cb = w_resync_finished;
-			drbd_queue_work(&mdev->data.work, w);
+			drbd_queue_work(&mdev->tconn->data.work, w);
 			return 1;
 		}
 		dev_err(DEV, "Warn failed to drbd_rs_del_all() and to kmalloc(w).\n");
@@ -1202,7 +1202,7 @@ int w_prev_work_done(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	struct drbd_tl_epoch *b = container_of(w, struct drbd_tl_epoch, w);
-	struct p_barrier *p = &mdev->data.sbuf.barrier;
+	struct p_barrier *p = &mdev->tconn->data.sbuf.barrier;
 	int ok = 1;
 
 	/* really avoid racing with tl_clear.  w.cb may have been referenced
@@ -1223,7 +1223,7 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	/* 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.  */
-	ok = _drbd_send_cmd(mdev, mdev->data.socket, P_BARRIER,
+	ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_BARRIER,
 				(struct p_header80 *)p, sizeof(*p), 0);
 	drbd_put_data_sock(mdev);
 
@@ -1621,18 +1621,18 @@ int drbd_worker(struct drbd_thread *thi)
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 
-		if (down_trylock(&mdev->data.work.s)) {
-			mutex_lock(&mdev->data.mutex);
-			if (mdev->data.socket && !mdev->tconn->net_conf->no_cork)
-				drbd_tcp_uncork(mdev->data.socket);
-			mutex_unlock(&mdev->data.mutex);
+		if (down_trylock(&mdev->tconn->data.work.s)) {
+			mutex_lock(&mdev->tconn->data.mutex);
+			if (mdev->tconn->data.socket && !mdev->tconn->net_conf->no_cork)
+				drbd_tcp_uncork(mdev->tconn->data.socket);
+			mutex_unlock(&mdev->tconn->data.mutex);
 
-			intr = down_interruptible(&mdev->data.work.s);
+			intr = down_interruptible(&mdev->tconn->data.work.s);
 
-			mutex_lock(&mdev->data.mutex);
-			if (mdev->data.socket  && !mdev->tconn->net_conf->no_cork)
-				drbd_tcp_cork(mdev->data.socket);
-			mutex_unlock(&mdev->data.mutex);
+			mutex_lock(&mdev->tconn->data.mutex);
+			if (mdev->tconn->data.socket  && !mdev->tconn->net_conf->no_cork)
+				drbd_tcp_cork(mdev->tconn->data.socket);
+			mutex_unlock(&mdev->tconn->data.mutex);
 		}
 
 		if (intr) {
@@ -1650,8 +1650,8 @@ int drbd_worker(struct drbd_thread *thi)
 		   this...   */
 
 		w = NULL;
-		spin_lock_irq(&mdev->data.work.q_lock);
-		if (!expect(!list_empty(&mdev->data.work.q))) {
+		spin_lock_irq(&mdev->tconn->data.work.q_lock);
+		if (!expect(!list_empty(&mdev->tconn->data.work.q))) {
 			/* something terribly wrong in our logic.
 			 * we were able to down() the semaphore,
 			 * but the list is empty... doh.
@@ -1663,12 +1663,12 @@ int drbd_worker(struct drbd_thread *thi)
 			 *
 			 * I'll try to get away just starting over this loop.
 			 */
-			spin_unlock_irq(&mdev->data.work.q_lock);
+			spin_unlock_irq(&mdev->tconn->data.work.q_lock);
 			continue;
 		}
-		w = list_entry(mdev->data.work.q.next, struct drbd_work, list);
+		w = list_entry(mdev->tconn->data.work.q.next, struct drbd_work, list);
 		list_del_init(&w->list);
-		spin_unlock_irq(&mdev->data.work.q_lock);
+		spin_unlock_irq(&mdev->tconn->data.work.q_lock);
 
 		if (!w->cb(mdev, w, mdev->state.conn < C_CONNECTED)) {
 			/* dev_warn(DEV, "worker: a callback failed! \n"); */
@@ -1680,11 +1680,11 @@ int drbd_worker(struct drbd_thread *thi)
 	D_ASSERT(test_bit(DEVICE_DYING, &mdev->flags));
 	D_ASSERT(test_bit(CONFIG_PENDING, &mdev->flags));
 
-	spin_lock_irq(&mdev->data.work.q_lock);
+	spin_lock_irq(&mdev->tconn->data.work.q_lock);
 	i = 0;
-	while (!list_empty(&mdev->data.work.q)) {
-		list_splice_init(&mdev->data.work.q, &work_list);
-		spin_unlock_irq(&mdev->data.work.q_lock);
+	while (!list_empty(&mdev->tconn->data.work.q)) {
+		list_splice_init(&mdev->tconn->data.work.q, &work_list);
+		spin_unlock_irq(&mdev->tconn->data.work.q_lock);
 
 		while (!list_empty(&work_list)) {
 			w = list_entry(work_list.next, struct drbd_work, list);
@@ -1693,15 +1693,15 @@ int drbd_worker(struct drbd_thread *thi)
 			i++; /* dead debugging code */
 		}
 
-		spin_lock_irq(&mdev->data.work.q_lock);
+		spin_lock_irq(&mdev->tconn->data.work.q_lock);
 	}
-	sema_init(&mdev->data.work.s, 0);
+	sema_init(&mdev->tconn->data.work.s, 0);
 	/* DANGEROUS race: if someone did queue his work within the spinlock,
 	 * but up() ed outside the spinlock, we could get an up() on the
 	 * semaphore without corresponding list entry.
 	 * So don't do that.
 	 */
-	spin_unlock_irq(&mdev->data.work.q_lock);
+	spin_unlock_irq(&mdev->tconn->data.work.q_lock);
 
 	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
 	/* _drbd_set_state only uses stop_nowait.
-- 
1.7.4.1


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

* [PATCH 032/118] drbd: moved receiver, worker and asender from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (30 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 031/118] drbd: moved data and meta " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 033/118] drbd: moved agreed_pro_version, last_received and ko_count " Philipp Reisner
                   ` (87 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Patch mostly:
sed -i -e 's/mdev->receiver/mdev->tconn->receiver/g' \
       -e 's/mdev->worker/mdev->tconn->worker/g' \
       -e 's/mdev->asender/mdev->tconn->asender/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_bitmap.c   |   24 +++++++++---------
 drivers/block/drbd/drbd_int.h      |    9 ++++---
 drivers/block/drbd/drbd_main.c     |   44 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_nl.c       |   10 ++++----
 drivers/block/drbd/drbd_receiver.c |   14 +++++-----
 drivers/block/drbd/drbd_worker.c   |    4 +-
 6 files changed, 53 insertions(+), 52 deletions(-)

diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index c756b4d..4da4c32 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -119,13 +119,13 @@ static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
 	if (!__ratelimit(&drbd_ratelimit_state))
 		return;
 	dev_err(DEV, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
-	    current == mdev->receiver.task ? "receiver" :
-	    current == mdev->asender.task  ? "asender"  :
-	    current == mdev->worker.task   ? "worker"   : current->comm,
+	    current == mdev->tconn->receiver.task ? "receiver" :
+	    current == mdev->tconn->asender.task  ? "asender"  :
+	    current == mdev->tconn->worker.task   ? "worker"   : current->comm,
 	    func, b->bm_why ?: "?",
-	    b->bm_task == mdev->receiver.task ? "receiver" :
-	    b->bm_task == mdev->asender.task  ? "asender"  :
-	    b->bm_task == mdev->worker.task   ? "worker"   : "?");
+	    b->bm_task == mdev->tconn->receiver.task ? "receiver" :
+	    b->bm_task == mdev->tconn->asender.task  ? "asender"  :
+	    b->bm_task == mdev->tconn->worker.task   ? "worker"   : "?");
 }
 
 void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
@@ -142,13 +142,13 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
 
 	if (trylock_failed) {
 		dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
-		    current == mdev->receiver.task ? "receiver" :
-		    current == mdev->asender.task  ? "asender"  :
-		    current == mdev->worker.task   ? "worker"   : current->comm,
+		    current == mdev->tconn->receiver.task ? "receiver" :
+		    current == mdev->tconn->asender.task  ? "asender"  :
+		    current == mdev->tconn->worker.task   ? "worker"   : current->comm,
 		    why, b->bm_why ?: "?",
-		    b->bm_task == mdev->receiver.task ? "receiver" :
-		    b->bm_task == mdev->asender.task  ? "asender"  :
-		    b->bm_task == mdev->worker.task   ? "worker"   : "?");
+		    b->bm_task == mdev->tconn->receiver.task ? "receiver" :
+		    b->bm_task == mdev->tconn->asender.task  ? "asender"  :
+		    b->bm_task == mdev->tconn->worker.task   ? "worker"   : "?");
 		mutex_lock(&b->bm_change);
 	}
 	if (BM_LOCKED_MASK & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 015ec05..6658dcb 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -972,6 +972,10 @@ struct drbd_tconn {			/* is a resource from the config file */
 
 	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
 	struct drbd_socket meta;	/* ping/ack (metadata) packets */
+
+	struct drbd_thread receiver;
+	struct drbd_thread worker;
+	struct drbd_thread asender;
 };
 
 struct drbd_conf {
@@ -1068,9 +1072,6 @@ struct drbd_conf {
 	struct crypto_hash *csums_tfm;
 	struct crypto_hash *verify_tfm;
 
-	struct drbd_thread receiver;
-	struct drbd_thread worker;
-	struct drbd_thread asender;
 	struct drbd_bitmap *bitmap;
 	unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */
 
@@ -2005,7 +2006,7 @@ drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
 static inline void wake_asender(struct drbd_conf *mdev)
 {
 	if (test_bit(SIGNAL_ASENDER, &mdev->flags))
-		force_sig(DRBD_SIG, mdev->asender.task);
+		force_sig(DRBD_SIG, mdev->tconn->asender.task);
 }
 
 static inline void request_ping(struct drbd_conf *mdev)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 84e40fb..5d8a6e9 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -613,7 +613,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	spin_unlock_irqrestore(&mdev->req_lock, flags);
 
 	if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
-		D_ASSERT(current != mdev->worker.task);
+		D_ASSERT(current != mdev->tconn->worker.task);
 		wait_for_completion(&done);
 	}
 
@@ -1229,16 +1229,16 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 
 	/* Receiver should clean up itself */
 	if (os.conn != C_DISCONNECTING && ns.conn == C_DISCONNECTING)
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_thread_stop_nowait(&mdev->tconn->receiver);
 
 	/* Now the receiver finished cleaning up itself, it should die */
 	if (os.conn != C_STANDALONE && ns.conn == C_STANDALONE)
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_thread_stop_nowait(&mdev->tconn->receiver);
 
 	/* Upon network failure, we need to restart the receiver. */
 	if (os.conn > C_TEAR_DOWN &&
 	    ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
-		drbd_thread_restart_nowait(&mdev->receiver);
+		drbd_thread_restart_nowait(&mdev->tconn->receiver);
 
 	/* Resume AL writing if we get a connection */
 	if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
@@ -1297,7 +1297,7 @@ int drbd_bitmap_io_from_worker(struct drbd_conf *mdev,
 {
 	int rv;
 
-	D_ASSERT(current == mdev->worker.task);
+	D_ASSERT(current == mdev->tconn->worker.task);
 
 	/* open coded non-blocking drbd_suspend_io(mdev); */
 	set_bit(SUSPEND_IO, &mdev->flags);
@@ -1598,7 +1598,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 
 	/* Upon network connection, we need to start the receiver */
 	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
-		drbd_thread_start(&mdev->receiver);
+		drbd_thread_start(&mdev->tconn->receiver);
 
 	/* Terminate worker thread if we are unconfigured - it will be
 	   restarted as needed... */
@@ -1609,7 +1609,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			resume_next_sg(mdev);
 		/* set in __drbd_set_state, unless CONFIG_PENDING was set */
 		if (test_bit(DEVICE_DYING, &mdev->flags))
-			drbd_thread_stop_nowait(&mdev->worker);
+			drbd_thread_stop_nowait(&mdev->tconn->worker);
 	}
 
 	drbd_md_sync(mdev);
@@ -1675,9 +1675,9 @@ int drbd_thread_start(struct drbd_thread *thi)
 	unsigned long flags;
 
 	const char *me =
-		thi == &mdev->receiver ? "receiver" :
-		thi == &mdev->asender  ? "asender"  :
-		thi == &mdev->worker   ? "worker"   : "NONSENSE";
+		thi == &mdev->tconn->receiver ? "receiver" :
+		thi == &mdev->tconn->asender  ? "asender"  :
+		thi == &mdev->tconn->worker   ? "worker"   : "NONSENSE";
 
 	/* is used from state engine doing drbd_thread_stop_nowait,
 	 * while holding the req lock irqsave */
@@ -1807,9 +1807,9 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 {
 	struct task_struct *p = current;
 	struct drbd_thread *thi =
-		p == mdev->asender.task  ? &mdev->asender  :
-		p == mdev->receiver.task ? &mdev->receiver :
-		p == mdev->worker.task   ? &mdev->worker   :
+		p == mdev->tconn->asender.task  ? &mdev->tconn->asender  :
+		p == mdev->tconn->receiver.task ? &mdev->tconn->receiver :
+		p == mdev->tconn->worker.task   ? &mdev->tconn->worker   :
 		NULL;
 	if (!expect(thi != NULL))
 		return;
@@ -2507,8 +2507,8 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 	/* long elapsed = (long)(jiffies - mdev->last_received); */
 
 	drop_it =   mdev->tconn->meta.socket == sock
-		|| !mdev->asender.task
-		|| get_t_state(&mdev->asender) != RUNNING
+		|| !mdev->tconn->asender.task
+		|| get_t_state(&mdev->tconn->asender) != RUNNING
 		|| mdev->state.conn < C_CONNECTED;
 
 	if (drop_it)
@@ -3034,9 +3034,9 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	init_waitqueue_head(&mdev->al_wait);
 	init_waitqueue_head(&mdev->seq_wait);
 
-	drbd_thread_init(mdev, &mdev->receiver, drbdd_init);
-	drbd_thread_init(mdev, &mdev->worker, drbd_worker);
-	drbd_thread_init(mdev, &mdev->asender, drbd_asender);
+	drbd_thread_init(mdev, &mdev->tconn->receiver, drbdd_init);
+	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker);
+	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender);
 
 	mdev->agreed_pro_version = PRO_VERSION_MAX;
 	mdev->write_ordering = WO_bdev_flush;
@@ -3048,9 +3048,9 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 void drbd_mdev_cleanup(struct drbd_conf *mdev)
 {
 	int i;
-	if (mdev->receiver.t_state != NONE)
+	if (mdev->tconn->receiver.t_state != NONE)
 		dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
-				mdev->receiver.t_state);
+				mdev->tconn->receiver.t_state);
 
 	/* no need to lock it, I'm the only thread alive */
 	if (atomic_read(&mdev->current_epoch->epoch_size) !=  0)
@@ -4032,7 +4032,7 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
 			  void (*done)(struct drbd_conf *, int),
 			  char *why, enum bm_flag flags)
 {
-	D_ASSERT(current == mdev->worker.task);
+	D_ASSERT(current == mdev->tconn->worker.task);
 
 	D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &mdev->flags));
 	D_ASSERT(!test_bit(BITMAP_IO, &mdev->flags));
@@ -4069,7 +4069,7 @@ int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *),
 {
 	int rv;
 
-	D_ASSERT(current != mdev->worker.task);
+	D_ASSERT(current != mdev->tconn->worker.task);
 
 	if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
 		drbd_suspend_io(mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a936d61..59bb58c 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -875,7 +875,7 @@ static void drbd_reconfig_start(struct drbd_conf *mdev)
 {
 	wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
 	wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
-	drbd_thread_start(&mdev->worker);
+	drbd_thread_start(&mdev->tconn->worker);
 	drbd_flush_workqueue(mdev);
 }
 
@@ -889,7 +889,7 @@ static void drbd_reconfig_done(struct drbd_conf *mdev)
 	    mdev->state.conn == C_STANDALONE &&
 	    mdev->state.role == R_SECONDARY) {
 		set_bit(DEVICE_DYING, &mdev->flags);
-		drbd_thread_stop_nowait(&mdev->worker);
+		drbd_thread_stop_nowait(&mdev->tconn->worker);
 	} else
 		clear_bit(CONFIG_PENDING, &mdev->flags);
 	spin_unlock_irq(&mdev->req_lock);
@@ -1887,9 +1887,9 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
 	if (!cpumask_equal(mdev->cpu_mask, new_cpu_mask)) {
 		cpumask_copy(mdev->cpu_mask, new_cpu_mask);
 		drbd_calc_cpu_mask(mdev);
-		mdev->receiver.reset_cpu_mask = 1;
-		mdev->asender.reset_cpu_mask = 1;
-		mdev->worker.reset_cpu_mask = 1;
+		mdev->tconn->receiver.reset_cpu_mask = 1;
+		mdev->tconn->asender.reset_cpu_mask = 1;
+		mdev->tconn->worker.reset_cpu_mask = 1;
 	}
 
 	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 2636bcc..e9f670c 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -833,7 +833,7 @@ retry:
 		if (signal_pending(current)) {
 			flush_signals(current);
 			smp_rmb();
-			if (get_t_state(&mdev->receiver) == EXITING)
+			if (get_t_state(&mdev->tconn->receiver) == EXITING)
 				goto out_release_sockets;
 		}
 
@@ -874,7 +874,7 @@ retry:
 	mdev->tconn->meta.socket = msock;
 	mdev->last_received = jiffies;
 
-	D_ASSERT(mdev->asender.task == NULL);
+	D_ASSERT(mdev->tconn->asender.task == NULL);
 
 	h = drbd_do_handshake(mdev);
 	if (h <= 0)
@@ -901,7 +901,7 @@ retry:
 	atomic_set(&mdev->packet_seq, 0);
 	mdev->peer_seq = 0;
 
-	drbd_thread_start(&mdev->asender);
+	drbd_thread_start(&mdev->tconn->asender);
 
 	if (drbd_send_protocol(mdev) == -1)
 		return -1;
@@ -3704,7 +3704,7 @@ static void drbdd(struct drbd_conf *mdev)
 	size_t shs; /* sub header size */
 	int rv;
 
-	while (get_t_state(&mdev->receiver) == RUNNING) {
+	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev);
 		if (!drbd_recv_header(mdev, &cmd, &packet_size))
 			goto err_out;
@@ -3768,7 +3768,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 		return;
 
 	/* asender does not clean up anything. it must not interfere, either */
-	drbd_thread_stop(&mdev->asender);
+	drbd_thread_stop(&mdev->tconn->asender);
 	drbd_free_sock(mdev);
 
 	/* wait for current activity to cease. */
@@ -3891,7 +3891,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
  */
 static int drbd_send_handshake(struct drbd_conf *mdev)
 {
-	/* ASSERT current == mdev->receiver ... */
+	/* ASSERT current == mdev->tconn->receiver ... */
 	struct p_handshake *p = &mdev->tconn->data.sbuf.handshake;
 	int ok;
 
@@ -3923,7 +3923,7 @@ static int drbd_send_handshake(struct drbd_conf *mdev)
  */
 static int drbd_do_handshake(struct drbd_conf *mdev)
 {
-	/* ASSERT current == mdev->receiver ... */
+	/* ASSERT current == mdev->tconn->receiver ... */
 	struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
 	const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
 	unsigned int length;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 9b1e2ba..1ca7856 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1705,8 +1705,8 @@ int drbd_worker(struct drbd_thread *thi)
 
 	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
 	/* _drbd_set_state only uses stop_nowait.
-	 * wait here for the EXITING receiver. */
-	drbd_thread_stop(&mdev->receiver);
+	 * wait here for the exiting receiver. */
+	drbd_thread_stop(&mdev->tconn->receiver);
 	drbd_mdev_cleanup(mdev);
 
 	dev_info(DEV, "worker terminated\n");
-- 
1.7.4.1


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

* [PATCH 033/118] drbd: moved agreed_pro_version, last_received and ko_count to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (31 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 032/118] drbd: moved receiver, worker and asender " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 034/118] drbd: moved req_lock and transfer log from mdev " Philipp Reisner
                   ` (86 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

sed -i \
       -e 's/mdev->agreed_pro_version/mdev->tconn->agreed_pro_version/g' \
       -e 's/mdev->last_received/mdev->tconn->last_received/g' \
       -e 's/mdev->ko_count/mdev->tconn->ko_count/g' \
       *.[ch]

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     |   32 ++++++++++++++--------------
 drivers/block/drbd/drbd_nl.c       |    8 +++---
 drivers/block/drbd/drbd_receiver.c |   40 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_req.c      |    2 +-
 drivers/block/drbd/drbd_worker.c   |    6 ++--
 6 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 6658dcb..ffc8211 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -972,6 +972,9 @@ struct drbd_tconn {			/* is a resource from the config file */
 
 	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
 	struct drbd_socket meta;	/* ping/ack (metadata) packets */
+	int agreed_pro_version;		/* actually used protocol version */
+	unsigned long last_received;	/* in jiffies, either socket */
+	unsigned int ko_count;
 
 	struct drbd_thread receiver;
 	struct drbd_thread worker;
@@ -994,9 +997,6 @@ struct drbd_conf {
 	struct block_device *this_bdev;
 	struct gendisk	    *vdisk;
 
-	int agreed_pro_version;  /* actually used protocol version */
-	unsigned long last_received; /* in jiffies, either socket */
-	unsigned int ko_count;
 	struct drbd_work  resync_work,
 			  unplug_work,
 			  go_diskless,
@@ -2297,7 +2297,7 @@ static inline int drbd_state_is_stable(struct drbd_conf *mdev)
 
 		/* Allow IO in BM exchange states with new protocols */
 	case C_WF_BITMAP_S:
-		if (mdev->agreed_pro_version < 96)
+		if (mdev->tconn->agreed_pro_version < 96)
 			return 0;
 		break;
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 5d8a6e9..e06ca4a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -735,7 +735,7 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 		rv = SS_NO_VERIFY_ALG;
 
 	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
-		  mdev->agreed_pro_version < 88)
+		  mdev->tconn->agreed_pro_version < 88)
 		rv = SS_NOT_SUPPORTED;
 
 	else if (ns.conn >= C_CONNECTED && ns.pdsk == D_UNKNOWN)
@@ -993,7 +993,7 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
 /* helper for __drbd_set_state */
 static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs)
 {
-	if (mdev->agreed_pro_version < 90)
+	if (mdev->tconn->agreed_pro_version < 90)
 		mdev->ov_start_sector = 0;
 	mdev->rs_total = drbd_bm_bits(mdev);
 	mdev->ov_position = 0;
@@ -1393,7 +1393,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 	 * which is unexpected. */
 	if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
 	    (ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
-	    mdev->agreed_pro_version >= 96 && get_ldev(mdev)) {
+	    mdev->tconn->agreed_pro_version >= 96 && get_ldev(mdev)) {
 		drbd_gen_and_send_sync_uuid(mdev);
 		put_ldev(mdev);
 	}
@@ -1902,7 +1902,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 	struct p_rs_param_95 *p;
 	struct socket *sock;
 	int size, rv;
-	const int apv = mdev->agreed_pro_version;
+	const int apv = mdev->tconn->agreed_pro_version;
 
 	size = apv <= 87 ? sizeof(struct p_rs_param)
 		: apv == 88 ? sizeof(struct p_rs_param)
@@ -1951,7 +1951,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 
 	size = sizeof(struct p_protocol);
 
-	if (mdev->agreed_pro_version >= 87)
+	if (mdev->tconn->agreed_pro_version >= 87)
 		size += strlen(mdev->tconn->net_conf->integrity_alg) + 1;
 
 	/* we must not recurse into our own queue,
@@ -1970,7 +1970,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	if (mdev->tconn->net_conf->want_lose)
 		cf |= CF_WANT_LOSE;
 	if (mdev->tconn->net_conf->dry_run) {
-		if (mdev->agreed_pro_version >= 92)
+		if (mdev->tconn->agreed_pro_version >= 92)
 			cf |= CF_DRY_RUN;
 		else {
 			dev_err(DEV, "--dry-run is not supported by peer");
@@ -1980,7 +1980,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	}
 	p->conn_flags    = cpu_to_be32(cf);
 
-	if (mdev->agreed_pro_version >= 87)
+	if (mdev->tconn->agreed_pro_version >= 87)
 		strcpy(p->integrity_alg, mdev->tconn->net_conf->integrity_alg);
 
 	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL,
@@ -2158,7 +2158,7 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
 
 	/* may we use this feature? */
 	if ((mdev->sync_conf.use_rle == 0) ||
-		(mdev->agreed_pro_version < 90))
+		(mdev->tconn->agreed_pro_version < 90))
 			return 0;
 
 	if (c->bit_offset >= c->bm_bits)
@@ -2404,7 +2404,7 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
 int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
 		     struct p_data *dp, int data_size)
 {
-	data_size -= (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
+	data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
 	return _drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size),
 			      dp->block_id);
@@ -2514,10 +2514,10 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 	if (drop_it)
 		return true;
 
-	drop_it = !--mdev->ko_count;
+	drop_it = !--mdev->tconn->ko_count;
 	if (!drop_it) {
 		dev_err(DEV, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
-		       current->comm, current->pid, mdev->ko_count);
+		       current->comm, current->pid, mdev->tconn->ko_count);
 		request_ping(mdev);
 	}
 
@@ -2647,7 +2647,7 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
 
 static u32 bio_flags_to_wire(struct drbd_conf *mdev, unsigned long bi_rw)
 {
-	if (mdev->agreed_pro_version >= 95)
+	if (mdev->tconn->agreed_pro_version >= 95)
 		return  (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
 			(bi_rw & REQ_FUA ? DP_FUA : 0) |
 			(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
@@ -2670,7 +2670,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	if (!drbd_get_data_sock(mdev))
 		return 0;
 
-	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
 	if (req->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
@@ -2755,7 +2755,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 	void *dgb;
 	int dgs;
 
-	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
 
 	if (e->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
@@ -2843,7 +2843,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 	msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
 
 	if (sock == mdev->tconn->data.socket) {
-		mdev->ko_count = mdev->tconn->net_conf->ko_count;
+		mdev->tconn->ko_count = mdev->tconn->net_conf->ko_count;
 		drbd_update_congested(mdev);
 	}
 	do {
@@ -3038,7 +3038,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker);
 	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender);
 
-	mdev->agreed_pro_version = PRO_VERSION_MAX;
+	mdev->tconn->agreed_pro_version = PRO_VERSION_MAX;
 	mdev->write_ordering = WO_bdev_flush;
 	mdev->resync_wenr = LC_FREE;
 	mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 59bb58c..a9ede8fc 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -845,9 +845,9 @@ void drbd_reconsider_max_bio_size(struct drbd_conf *mdev)
 	   Because new from 8.3.8 onwards the peer can use multiple
 	   BIOs for a single peer_request */
 	if (mdev->state.conn >= C_CONNECTED) {
-		if (mdev->agreed_pro_version < 94)
+		if (mdev->tconn->agreed_pro_version < 94)
 			peer = mdev->peer_max_bio_size;
-		else if (mdev->agreed_pro_version == 94)
+		else if (mdev->tconn->agreed_pro_version == 94)
 			peer = DRBD_MAX_SIZE_H80_PACKET;
 		else /* drbd 8.3.8 onwards */
 			peer = DRBD_MAX_BIO_SIZE;
@@ -1675,7 +1675,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		goto fail;
 	}
 
-	if (rs.no_resync && mdev->agreed_pro_version < 93) {
+	if (rs.no_resync && mdev->tconn->agreed_pro_version < 93) {
 		retcode = ERR_NEED_APV_93;
 		goto fail;
 	}
@@ -2170,7 +2170,7 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 	}
 
 	/* this is "skip initial sync", assume to be clean */
-	if (mdev->state.conn == C_CONNECTED && mdev->agreed_pro_version >= 90 &&
+	if (mdev->state.conn == C_CONNECTED && mdev->tconn->agreed_pro_version >= 90 &&
 	    mdev->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
 		dev_info(DEV, "Preparing to skip initial sync\n");
 		skip_initial_sync = 1;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e9f670c..27a8363 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -872,7 +872,7 @@ retry:
 
 	mdev->tconn->data.socket = sock;
 	mdev->tconn->meta.socket = msock;
-	mdev->last_received = jiffies;
+	mdev->tconn->last_received = jiffies;
 
 	D_ASSERT(mdev->tconn->asender.task == NULL);
 
@@ -948,7 +948,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi
 		    be16_to_cpu(h->h80.length));
 		return false;
 	}
-	mdev->last_received = jiffies;
+	mdev->tconn->last_received = jiffies;
 
 	return true;
 }
@@ -1244,7 +1244,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __
 	void *dig_vv = mdev->int_dig_vv;
 	unsigned long *data;
 
-	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
 
 	if (dgs) {
@@ -1361,7 +1361,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 	void *dig_in = mdev->int_dig_in;
 	void *dig_vv = mdev->int_dig_vv;
 
-	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
 		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
 
 	if (dgs) {
@@ -2048,7 +2048,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un
 			goto out_free_e;
 
 		if (cmd == P_CSUM_RS_REQUEST) {
-			D_ASSERT(mdev->agreed_pro_version >= 89);
+			D_ASSERT(mdev->tconn->agreed_pro_version >= 89);
 			e->w.cb = w_e_end_csum_rs_req;
 			/* used in the sector offset progress display */
 			mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2065,7 +2065,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un
 
 	case P_OV_REQUEST:
 		if (mdev->ov_start_sector == ~(sector_t)0 &&
-		    mdev->agreed_pro_version >= 90) {
+		    mdev->tconn->agreed_pro_version >= 90) {
 			unsigned long now = jiffies;
 			int i;
 			mdev->ov_start_sector = sector;
@@ -2360,7 +2360,7 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
 
 		if (mdev->p_uuid[UI_BITMAP] == (u64)0 && mdev->ldev->md.uuid[UI_BITMAP] != (u64)0) {
 
-			if (mdev->agreed_pro_version < 91)
+			if (mdev->tconn->agreed_pro_version < 91)
 				return -1091;
 
 			if ((mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1)) &&
@@ -2381,7 +2381,7 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
 
 		if (mdev->ldev->md.uuid[UI_BITMAP] == (u64)0 && mdev->p_uuid[UI_BITMAP] != (u64)0) {
 
-			if (mdev->agreed_pro_version < 91)
+			if (mdev->tconn->agreed_pro_version < 91)
 				return -1091;
 
 			if ((mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (mdev->p_uuid[UI_BITMAP] & ~((u64)1)) &&
@@ -2427,14 +2427,14 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
 	*rule_nr = 51;
 	peer = mdev->p_uuid[UI_HISTORY_START] & ~((u64)1);
 	if (self == peer) {
-		if (mdev->agreed_pro_version < 96 ?
+		if (mdev->tconn->agreed_pro_version < 96 ?
 		    (mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) ==
 		    (mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1)) :
 		    peer + UUID_NEW_BM_OFFSET == (mdev->p_uuid[UI_BITMAP] & ~((u64)1))) {
 			/* The last P_SYNC_UUID did not get though. Undo the last start of
 			   resync as sync source modifications of the peer's UUIDs. */
 
-			if (mdev->agreed_pro_version < 91)
+			if (mdev->tconn->agreed_pro_version < 91)
 				return -1091;
 
 			mdev->p_uuid[UI_BITMAP] = mdev->p_uuid[UI_HISTORY_START];
@@ -2464,14 +2464,14 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
 	*rule_nr = 71;
 	self = mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1);
 	if (self == peer) {
-		if (mdev->agreed_pro_version < 96 ?
+		if (mdev->tconn->agreed_pro_version < 96 ?
 		    (mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) ==
 		    (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1)) :
 		    self + UUID_NEW_BM_OFFSET == (mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1))) {
 			/* The last P_SYNC_UUID did not get though. Undo the last start of
 			   resync as sync source modifications of our UUIDs. */
 
-			if (mdev->agreed_pro_version < 91)
+			if (mdev->tconn->agreed_pro_version < 91)
 				return -1091;
 
 			_drbd_uuid_set(mdev, UI_BITMAP, mdev->ldev->md.uuid[UI_HISTORY_START]);
@@ -2731,7 +2731,7 @@ static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsig
 		goto disconnect;
 	}
 
-	if (mdev->agreed_pro_version >= 87) {
+	if (mdev->tconn->agreed_pro_version >= 87) {
 		unsigned char *my_alg = mdev->tconn->net_conf->integrity_alg;
 
 		if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size)
@@ -2787,7 +2787,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	unsigned int header_size, data_size, exp_max_sz;
 	struct crypto_hash *verify_tfm = NULL;
 	struct crypto_hash *csums_tfm = NULL;
-	const int apv = mdev->agreed_pro_version;
+	const int apv = mdev->tconn->agreed_pro_version;
 	int *rs_plan_s = NULL;
 	int fifo_size = 0;
 
@@ -3074,7 +3074,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	if (get_ldev(mdev)) {
 		int skip_initial_sync =
 			mdev->state.conn == C_CONNECTED &&
-			mdev->agreed_pro_version >= 90 &&
+			mdev->tconn->agreed_pro_version >= 90 &&
 			mdev->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
 			(p_uuid[UI_FLAGS] & 8);
 		if (skip_initial_sync) {
@@ -3967,10 +3967,10 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	    PRO_VERSION_MIN > p->protocol_max)
 		goto incompat;
 
-	mdev->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
+	mdev->tconn->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
 
 	dev_info(DEV, "Handshake successful: "
-	     "Agreed network protocol version %d\n", mdev->agreed_pro_version);
+	     "Agreed network protocol version %d\n", mdev->tconn->agreed_pro_version);
 
 	return 1;
 
@@ -4220,7 +4220,7 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
 	sector_t sector = be64_to_cpu(p->sector);
 	int blksize = be32_to_cpu(p->blksize);
 
-	D_ASSERT(mdev->agreed_pro_version >= 89);
+	D_ASSERT(mdev->tconn->agreed_pro_version >= 89);
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
 
@@ -4560,7 +4560,7 @@ int drbd_asender(struct drbd_thread *thi)
 		} else if (rv == -EAGAIN) {
 			/* If the data socket received something meanwhile,
 			 * that is good enough: peer is still alive. */
-			if (time_after(mdev->last_received,
+			if (time_after(mdev->tconn->last_received,
 				jiffies - mdev->tconn->meta.socket->sk->sk_rcvtimeo))
 				continue;
 			if (ping_timeout_active) {
@@ -4598,7 +4598,7 @@ int drbd_asender(struct drbd_thread *thi)
 				goto reconnect;
 		}
 		if (received == expect) {
-			mdev->last_received = jiffies;
+			mdev->tconn->last_received = jiffies;
 			D_ASSERT(cmd != NULL);
 			if (!cmd->process(mdev, h))
 				goto reconnect;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index ac43e44..c871ef2 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -951,7 +951,7 @@ allocate_barrier:
 		_req_mod(req, QUEUE_FOR_SEND_OOS);
 
 	if (remote &&
-	    mdev->tconn->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
+	    mdev->tconn->net_conf->on_congestion != OC_BLOCK && mdev->tconn->agreed_pro_version >= 96) {
 		int congested = 0;
 
 		if (mdev->tconn->net_conf->cong_fill &&
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 1ca7856..ec26df3 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -616,7 +616,7 @@ next_sector:
 		/* adjust very last sectors, in case we are oddly sized */
 		if (sector + (size>>9) > capacity)
 			size = (capacity-sector)<<9;
-		if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) {
+		if (mdev->tconn->agreed_pro_version >= 89 && mdev->csums_tfm) {
 			switch (read_for_csum(mdev, sector, size)) {
 			case -EIO: /* Disk failure */
 				put_ldev(mdev);
@@ -1574,10 +1574,10 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 		 * drbd_resync_finished from here in that case.
 		 * We drbd_gen_and_send_sync_uuid here for protocol < 96,
 		 * and from after_state_ch otherwise. */
-		if (side == C_SYNC_SOURCE && mdev->agreed_pro_version < 96)
+		if (side == C_SYNC_SOURCE && mdev->tconn->agreed_pro_version < 96)
 			drbd_gen_and_send_sync_uuid(mdev);
 
-		if (mdev->agreed_pro_version < 95 && mdev->rs_total == 0) {
+		if (mdev->tconn->agreed_pro_version < 95 && mdev->rs_total == 0) {
 			/* This still has a race (about when exactly the peers
 			 * detect connection loss) that can lead to a full sync
 			 * on next handshake. In 8.3.9 we fixed this with explicit
-- 
1.7.4.1


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

* [PATCH 034/118] drbd: moved req_lock and transfer log from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (32 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 033/118] drbd: moved agreed_pro_version, last_received and ko_count " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 035/118] drbd: moved crypto transformations and friends " Philipp Reisner
                   ` (85 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

sed -i \
       -e 's/mdev->req_lock/mdev->tconn->req_lock/g' \
       -e 's/mdev->unused_spare_tle/mdev->tconn->unused_spare_tle/g' \
       -e 's/mdev->newest_tle/mdev->tconn->newest_tle/g' \
       -e 's/mdev->oldest_tle/mdev->tconn->oldest_tle/g' \
       -e 's/mdev->out_of_sequence_requests/mdev->tconn->out_of_sequence_requests/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   20 ++++----
 drivers/block/drbd/drbd_main.c     |  100 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_nl.c       |   34 ++++++------
 drivers/block/drbd/drbd_receiver.c |   96 +++++++++++++++++-----------------
 drivers/block/drbd/drbd_req.c      |   48 +++++++++---------
 drivers/block/drbd/drbd_req.h      |    4 +-
 drivers/block/drbd/drbd_worker.c   |   38 +++++++-------
 7 files changed, 170 insertions(+), 170 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ffc8211..0e9debe 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -976,6 +976,12 @@ struct drbd_tconn {			/* is a resource from the config file */
 	unsigned long last_received;	/* in jiffies, either socket */
 	unsigned int ko_count;
 
+	spinlock_t req_lock;
+	struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */
+	struct drbd_tl_epoch *newest_tle;
+	struct drbd_tl_epoch *oldest_tle;
+	struct list_head out_of_sequence_requests;
+
 	struct drbd_thread receiver;
 	struct drbd_thread worker;
 	struct drbd_thread asender;
@@ -1031,12 +1037,6 @@ struct drbd_conf {
 	atomic_t unacked_cnt;	 /* Need to send replys for */
 	atomic_t local_cnt;	 /* Waiting for local completion */
 
-	spinlock_t req_lock;
-	struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */
-	struct drbd_tl_epoch *newest_tle;
-	struct drbd_tl_epoch *oldest_tle;
-	struct list_head out_of_sequence_requests;
-
 	/* Interval tree of pending local write requests */
 	struct rb_root read_requests;
 	struct rb_root write_requests;
@@ -1868,9 +1868,9 @@ static inline void drbd_chk_io_error_(struct drbd_conf *mdev,
 {
 	if (error) {
 		unsigned long flags;
-		spin_lock_irqsave(&mdev->req_lock, flags);
+		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 		__drbd_chk_io_error_(mdev, forcedetach, where);
-		spin_unlock_irqrestore(&mdev->req_lock, flags);
+		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 	}
 }
 
@@ -2366,11 +2366,11 @@ static inline bool inc_ap_bio_cond(struct drbd_conf *mdev, int count)
 {
 	bool rv = false;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	rv = may_inc_ap_bio(mdev);
 	if (rv)
 		atomic_add(count, &mdev->ap_bio_cnt);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	return rv;
 }
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e06ca4a..c063cd5 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -185,7 +185,7 @@ int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins)
  * DOC: The transfer log
  *
  * The transfer log is a single linked list of &struct drbd_tl_epoch objects.
- * mdev->newest_tle points to the head, mdev->oldest_tle points to the tail
+ * mdev->tconn->newest_tle points to the head, mdev->tconn->oldest_tle points to the tail
  * of the list. There is always at least one &struct drbd_tl_epoch object.
  *
  * Each &struct drbd_tl_epoch has a circular double linked list of requests
@@ -206,21 +206,21 @@ static int tl_init(struct drbd_conf *mdev)
 	b->n_writes = 0;
 	b->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */
 
-	mdev->oldest_tle = b;
-	mdev->newest_tle = b;
-	INIT_LIST_HEAD(&mdev->out_of_sequence_requests);
+	mdev->tconn->oldest_tle = b;
+	mdev->tconn->newest_tle = b;
+	INIT_LIST_HEAD(&mdev->tconn->out_of_sequence_requests);
 
 	return 1;
 }
 
 static void tl_cleanup(struct drbd_conf *mdev)
 {
-	D_ASSERT(mdev->oldest_tle == mdev->newest_tle);
-	D_ASSERT(list_empty(&mdev->out_of_sequence_requests));
-	kfree(mdev->oldest_tle);
-	mdev->oldest_tle = NULL;
-	kfree(mdev->unused_spare_tle);
-	mdev->unused_spare_tle = NULL;
+	D_ASSERT(mdev->tconn->oldest_tle == mdev->tconn->newest_tle);
+	D_ASSERT(list_empty(&mdev->tconn->out_of_sequence_requests));
+	kfree(mdev->tconn->oldest_tle);
+	mdev->tconn->oldest_tle = NULL;
+	kfree(mdev->tconn->unused_spare_tle);
+	mdev->tconn->unused_spare_tle = NULL;
 }
 
 /**
@@ -240,13 +240,13 @@ void _tl_add_barrier(struct drbd_conf *mdev, struct drbd_tl_epoch *new)
 	new->next = NULL;
 	new->n_writes = 0;
 
-	newest_before = mdev->newest_tle;
+	newest_before = mdev->tconn->newest_tle;
 	/* never send a barrier number == 0, because that is special-cased
 	 * when using TCQ for our write ordering code */
 	new->br_number = (newest_before->br_number+1) ?: 1;
-	if (mdev->newest_tle != new) {
-		mdev->newest_tle->next = new;
-		mdev->newest_tle = new;
+	if (mdev->tconn->newest_tle != new) {
+		mdev->tconn->newest_tle->next = new;
+		mdev->tconn->newest_tle = new;
 	}
 }
 
@@ -267,9 +267,9 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 	struct list_head *le, *tle;
 	struct drbd_request *r;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 
-	b = mdev->oldest_tle;
+	b = mdev->tconn->oldest_tle;
 
 	/* first some paranoia code */
 	if (b == NULL) {
@@ -312,22 +312,22 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 	if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) {
 		_tl_add_barrier(mdev, b);
 		if (nob)
-			mdev->oldest_tle = nob;
+			mdev->tconn->oldest_tle = nob;
 		/* if nob == NULL b was the only barrier, and becomes the new
-		   barrier. Therefore mdev->oldest_tle points already to b */
+		   barrier. Therefore mdev->tconn->oldest_tle points already to b */
 	} else {
 		D_ASSERT(nob != NULL);
-		mdev->oldest_tle = nob;
+		mdev->tconn->oldest_tle = nob;
 		kfree(b);
 	}
 
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	dec_ap_pending(mdev);
 
 	return;
 
 bail:
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
 }
 
@@ -347,8 +347,8 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 	struct drbd_request *req;
 	int rv, n_writes, n_reads;
 
-	b = mdev->oldest_tle;
-	pn = &mdev->oldest_tle;
+	b = mdev->tconn->oldest_tle;
+	pn = &mdev->tconn->oldest_tle;
 	while (b) {
 		n_writes = 0;
 		n_reads = 0;
@@ -387,7 +387,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 			if (b->w.cb != NULL)
 				dec_ap_pending(mdev);
 
-			if (b == mdev->newest_tle) {
+			if (b == mdev->tconn->newest_tle) {
 				/* recycle, but reinit! */
 				D_ASSERT(tmp == NULL);
 				INIT_LIST_HEAD(&b->requests);
@@ -422,15 +422,15 @@ void tl_clear(struct drbd_conf *mdev)
 	struct list_head *le, *tle;
 	struct drbd_request *r;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 
 	_tl_restart(mdev, CONNECTION_LOST_WHILE_PENDING);
 
 	/* we expect this list to be empty. */
-	D_ASSERT(list_empty(&mdev->out_of_sequence_requests));
+	D_ASSERT(list_empty(&mdev->tconn->out_of_sequence_requests));
 
 	/* but just in case, clean it up anyways! */
-	list_for_each_safe(le, tle, &mdev->out_of_sequence_requests) {
+	list_for_each_safe(le, tle, &mdev->tconn->out_of_sequence_requests) {
 		r = list_entry(le, struct drbd_request, tl_requests);
 		/* It would be nice to complete outside of spinlock.
 		 * But this is easier for now. */
@@ -440,14 +440,14 @@ void tl_clear(struct drbd_conf *mdev)
 	/* ensure bit indicating barrier is required is clear */
 	clear_bit(CREATE_BARRIER, &mdev->flags);
 
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 }
 
 void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 {
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	_tl_restart(mdev, what);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 }
 
 /**
@@ -476,12 +476,12 @@ drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
 	union drbd_state os, ns;
 	enum drbd_state_rv rv;
 
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
 	rv = _drbd_set_state(mdev, ns, f, NULL);
 	ns = mdev->state;
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	return rv;
 }
@@ -522,7 +522,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 		return SS_CW_FAILED_BY_PEER;
 
 	rv = 0;
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
 	ns = sanitize_state(mdev, os, ns, NULL);
@@ -537,7 +537,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 				rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
 		}
 	}
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	return rv;
 }
@@ -566,7 +566,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	if (f & CS_SERIALIZE)
 		mutex_lock(&mdev->state_mutex);
 
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
 	ns = sanitize_state(mdev, os, ns, NULL);
@@ -575,7 +575,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS)
 			rv = is_valid_state_transition(mdev, ns, os);
-		spin_unlock_irqrestore(&mdev->req_lock, flags);
+		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 		if (rv < SS_SUCCESS) {
 			if (f & CS_VERBOSE)
@@ -601,7 +601,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 				print_st_err(mdev, os, ns, rv);
 			goto abort;
 		}
-		spin_lock_irqsave(&mdev->req_lock, flags);
+		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 		os = mdev->state;
 		ns.i = (os.i & ~mask.i) | val.i;
 		rv = _drbd_set_state(mdev, ns, f, &done);
@@ -610,7 +610,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 		rv = _drbd_set_state(mdev, ns, f, &done);
 	}
 
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
 		D_ASSERT(current != mdev->tconn->worker.task);
@@ -1367,9 +1367,9 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 				drbd_uuid_new_current(mdev);
 				clear_bit(NEW_CUR_UUID, &mdev->flags);
 			}
-			spin_lock_irq(&mdev->req_lock);
+			spin_lock_irq(&mdev->tconn->req_lock);
 			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
-			spin_unlock_irq(&mdev->req_lock);
+			spin_unlock_irq(&mdev->tconn->req_lock);
 		}
 		/* case2: The connection was established again: */
 		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
@@ -1380,11 +1380,11 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 	}
 
 	if (what != NOTHING) {
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 		_tl_restart(mdev, what);
 		nsm.i &= mdev->state.i;
 		_drbd_set_state(mdev, nsm, CS_VERBOSE, NULL);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 	}
 
 	/* Became sync source.  With protocol >= 96, we still need to send out
@@ -2898,7 +2898,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
 	int rv = 0;
 
 	mutex_lock(&drbd_main_mutex);
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	/* to have a stable mdev->state.role
 	 * and no race with updating open_cnt */
 
@@ -2911,7 +2911,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
 
 	if (!rv)
 		mdev->open_cnt++;
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 	mutex_unlock(&drbd_main_mutex);
 
 	return rv;
@@ -2990,7 +2990,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	spin_lock_init(&mdev->tconn->meta.work.q_lock);
 
 	spin_lock_init(&mdev->al_lock);
-	spin_lock_init(&mdev->req_lock);
+	spin_lock_init(&mdev->tconn->req_lock);
 	spin_lock_init(&mdev->peer_seq_lock);
 	spin_lock_init(&mdev->epoch_lock);
 
@@ -3451,7 +3451,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
 	blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
 	blk_queue_merge_bvec(q, drbd_merge_bvec);
-	q->queue_lock = &mdev->req_lock;
+	q->queue_lock = &mdev->tconn->req_lock; /* needed since we use */
 
 	mdev->md_io_page = alloc_page(GFP_KERNEL);
 	if (!mdev->md_io_page)
@@ -3784,14 +3784,14 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
 	mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents);
 	bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->state.conn < C_CONNECTED) {
 		int peer;
 		peer = be32_to_cpu(buffer->la_peer_max_bio_size);
 		peer = max_t(int, peer, DRBD_MAX_BIO_SIZE_SAFE);
 		mdev->peer_max_bio_size = peer;
 	}
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (mdev->sync_conf.al_extents < 7)
 		mdev->sync_conf.al_extents = 127;
@@ -4046,13 +4046,13 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
 	mdev->bm_io_work.why = why;
 	mdev->bm_io_work.flags = flags;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	set_bit(BITMAP_IO, &mdev->flags);
 	if (atomic_read(&mdev->ap_bio_cnt) == 0) {
 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags))
 			drbd_queue_work(&mdev->tconn->data.work, &mdev->bm_io_work.w);
 	}
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 }
 
 /**
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a9ede8fc..4eaf81a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -287,13 +287,13 @@ static int _try_outdate_peer_async(void *data)
 	   pdsk == D_INCONSISTENT while conn >= C_CONNECTED is valid,
 	   therefore we have to have the pre state change check here.
 	*/
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	ns = mdev->state;
 	if (ns.conn < C_WF_REPORT_PARAMS) {
 		ns.pdsk = nps;
 		_drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
 	}
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	return 0;
 }
@@ -884,7 +884,7 @@ static void drbd_reconfig_start(struct drbd_conf *mdev)
  * wakes potential waiters */
 static void drbd_reconfig_done(struct drbd_conf *mdev)
 {
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->state.disk == D_DISKLESS &&
 	    mdev->state.conn == C_STANDALONE &&
 	    mdev->state.role == R_SECONDARY) {
@@ -892,7 +892,7 @@ static void drbd_reconfig_done(struct drbd_conf *mdev)
 		drbd_thread_stop_nowait(&mdev->tconn->worker);
 	} else
 		clear_bit(CONFIG_PENDING, &mdev->flags);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	wake_up(&mdev->state_wait);
 }
 
@@ -909,11 +909,11 @@ static void drbd_suspend_al(struct drbd_conf *mdev)
 		return;
 	}
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->state.conn < C_CONNECTED)
 		s = !test_and_set_bit(AL_SUSPENDED, &mdev->flags);
 
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (s)
 		dev_info(DEV, "Suspended AL updates\n");
@@ -1240,7 +1240,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 	if (_drbd_bm_total_weight(mdev) == drbd_bm_bits(mdev))
 		drbd_suspend_al(mdev); /* IO is still suspended here... */
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	os = mdev->state;
 	ns.i = os.i;
 	/* If MDF_CONSISTENT is not set go into inconsistent state,
@@ -1285,7 +1285,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 
 	rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
 	ns = mdev->state;
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (rv < SS_SUCCESS)
 		goto force_diskless_dec;
@@ -1521,10 +1521,10 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 	}
 
 	drbd_flush_workqueue(mdev);
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->tconn->net_conf != NULL) {
 		retcode = ERR_NET_CONFIGURED;
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		goto fail;
 	}
 	mdev->tconn->net_conf = new_conf;
@@ -1548,7 +1548,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 	mdev->int_dig_in=int_dig_in;
 	mdev->int_dig_vv=int_dig_vv;
 	retcode = _drbd_set_state(_NS(mdev, conn, C_UNCONNECTED), CS_VERBOSE, NULL);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
 	reply->ret_code = retcode;
@@ -1582,10 +1582,10 @@ static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 	}
 
 	if (dc.force) {
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 		if (mdev->state.conn >= C_WF_CONNECTION)
 			_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), CS_HARD, NULL);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		goto done;
 	}
 
@@ -1917,10 +1917,10 @@ static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 		retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T));
 
 	while (retcode == SS_NEED_CONNECTION) {
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 		if (mdev->state.conn < C_CONNECTED)
 			retcode = _drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_VERBOSE, NULL);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 
 		if (retcode != SS_NEED_CONNECTION)
 			break;
@@ -2193,10 +2193,10 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 			drbd_send_uuids_skip_initial_sync(mdev);
 			_drbd_uuid_set(mdev, UI_BITMAP, 0);
 			drbd_print_uuids(mdev, "cleared bitmap UUID");
-			spin_lock_irq(&mdev->req_lock);
+			spin_lock_irq(&mdev->tconn->req_lock);
 			_drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
 					CS_VERBOSE, NULL);
-			spin_unlock_irq(&mdev->req_lock);
+			spin_unlock_irq(&mdev->tconn->req_lock);
 		}
 	}
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 27a8363..af968a0b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -210,9 +210,9 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev)
 	LIST_HEAD(reclaimed);
 	struct drbd_epoch_entry *e, *t;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	reclaim_net_ee(mdev, &reclaimed);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	list_for_each_entry_safe(e, t, &reclaimed, w.list)
 		drbd_free_net_ee(mdev, e);
@@ -269,7 +269,7 @@ static struct page *drbd_pp_alloc(struct drbd_conf *mdev, unsigned number, bool
 }
 
 /* Must not be used from irq, as that may deadlock: see drbd_pp_alloc.
- * Is also used from inside an other spin_lock_irq(&mdev->req_lock);
+ * Is also used from inside an other spin_lock_irq(&mdev->tconn->req_lock);
  * Either links the page chain back to the global pool,
  * or returns all pages to the system. */
 static void drbd_pp_free(struct drbd_conf *mdev, struct page *page, int is_net)
@@ -371,9 +371,9 @@ int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 	int count = 0;
 	int is_net = list == &mdev->net_ee;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_splice_init(list, &work_list);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	list_for_each_entry_safe(e, t, &work_list, w.list) {
 		drbd_free_some_ee(mdev, e, is_net);
@@ -399,10 +399,10 @@ static int drbd_process_done_ee(struct drbd_conf *mdev)
 	struct drbd_epoch_entry *e, *t;
 	int ok = (mdev->state.conn >= C_WF_REPORT_PARAMS);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	reclaim_net_ee(mdev, &reclaimed);
 	list_splice_init(&mdev->done_ee, &work_list);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	list_for_each_entry_safe(e, t, &reclaimed, w.list)
 		drbd_free_net_ee(mdev, e);
@@ -429,18 +429,18 @@ void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
 	 * and calling prepare_to_wait in the fast path */
 	while (!list_empty(head)) {
 		prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		io_schedule();
 		finish_wait(&mdev->ee_wait, &wait);
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 	}
 }
 
 void drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
 {
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	_drbd_wait_ee_list_empty(mdev, head);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 }
 
 /* see also kernel_accept; which is only present since 2.6.18.
@@ -1452,9 +1452,9 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
 
 	e->w.cb = e_end_resync_block;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_add(&e->w.list, &mdev->sync_ee);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	atomic_add(data_size >> 9, &mdev->rs_sect_ev);
 	if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0)
@@ -1462,9 +1462,9 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_del(&e->w.list);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	drbd_free_ee(mdev, e);
 fail:
@@ -1498,9 +1498,9 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 
 	sector = be64_to_cpu(p->sector);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	req = find_request(mdev, &mdev->read_requests, p->block_id, sector, false, __func__);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	if (unlikely(!req))
 		return false;
 
@@ -1574,11 +1574,11 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	/* we delete from the conflict detection hash _after_ we sent out the
 	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
 	if (mdev->tconn->net_conf->two_primaries) {
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 		D_ASSERT(!drbd_interval_empty(&e->i));
 		drbd_remove_interval(&mdev->epoch_entries, &e->i);
 		drbd_clear_interval(&e->i);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 	} else
 		D_ASSERT(drbd_interval_empty(&e->i));
 
@@ -1595,11 +1595,11 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 	D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	D_ASSERT(!drbd_interval_empty(&e->i));
 	drbd_remove_interval(&mdev->epoch_entries, &e->i);
 	drbd_clear_interval(&e->i);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	dec_unacked(mdev);
 
@@ -1718,7 +1718,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 	/* I'm the receiver, I do hold a net_cnt reference. */
 	if (!mdev->tconn->net_conf->two_primaries) {
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 	} else {
 		/* don't get the req_lock yet,
 		 * we may sleep in drbd_wait_peer_seq */
@@ -1765,7 +1765,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		if (drbd_wait_peer_seq(mdev, be32_to_cpu(p->seq_num)))
 			goto out_interrupted;
 
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 
 		drbd_insert_interval(&mdev->epoch_entries, &e->i);
 
@@ -1805,7 +1805,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 				e->w.cb = e_send_discard_ack;
 				list_add_tail(&e->w.list, &mdev->done_ee);
 
-				spin_unlock_irq(&mdev->req_lock);
+				spin_unlock_irq(&mdev->tconn->req_lock);
 
 				/* we could probably send that P_DISCARD_ACK ourselves,
 				 * but I don't like the receiver using the msock */
@@ -1820,13 +1820,13 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 				drbd_remove_interval(&mdev->epoch_entries, &e->i);
 				drbd_clear_interval(&e->i);
 
-				spin_unlock_irq(&mdev->req_lock);
+				spin_unlock_irq(&mdev->tconn->req_lock);
 
 				finish_wait(&mdev->misc_wait, &wait);
 				goto out_interrupted;
 			}
 
-			spin_unlock_irq(&mdev->req_lock);
+			spin_unlock_irq(&mdev->tconn->req_lock);
 			if (first) {
 				first = 0;
 				dev_alert(DEV, "Concurrent write! [W AFTERWARDS] "
@@ -1837,13 +1837,13 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 				D_ASSERT(have_unacked == 0);
 			}
 			schedule();
-			spin_lock_irq(&mdev->req_lock);
+			spin_lock_irq(&mdev->tconn->req_lock);
 		}
 		finish_wait(&mdev->misc_wait, &wait);
 	}
 
 	list_add(&e->w.list, &mdev->active_ee);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	switch (mdev->tconn->net_conf->wire_protocol) {
 	case DRBD_PROT_C:
@@ -1874,11 +1874,11 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_del(&e->w.list);
 	drbd_remove_interval(&mdev->epoch_entries, &e->i);
 	drbd_clear_interval(&e->i);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	if (e->flags & EE_CALL_AL_COMPLETE_IO)
 		drbd_al_complete_io(mdev, e->i.sector);
 
@@ -2122,18 +2122,18 @@ submit_for_resync:
 
 submit:
 	inc_unacked(mdev);
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_add_tail(&e->w.list, &mdev->read_ee);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
 		return true;
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_del(&e->w.list);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	/* no drbd_rs_complete_io(), we are dropping the connection anyways */
 
 out_free_e:
@@ -3183,10 +3183,10 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		dev_info(DEV, "real peer disk state = %s\n", drbd_disk_str(real_peer_disk));
 	}
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
  retry:
 	os = ns = mdev->state;
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	/* peer says his disk is uptodate, while we think it is inconsistent,
 	 * and this happens while we think we have a sync going on. */
@@ -3270,7 +3270,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 		}
 	}
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->state.i != os.i)
 		goto retry;
 	clear_bit(CONSIDER_RESYNC, &mdev->flags);
@@ -3284,7 +3284,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	    test_bit(NEW_CUR_UUID, &mdev->flags)) {
 		/* Do not allow tl_restart(RESEND) for a rebooted peer. We can only allow this
 		   for temporal network outages! */
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		dev_err(DEV, "Aborting Connect, can not thaw IO with an only Consistent peer\n");
 		tl_clear(mdev);
 		drbd_uuid_new_current(mdev);
@@ -3294,7 +3294,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	}
 	rv = _drbd_set_state(mdev, ns, cs_flags, NULL);
 	ns = mdev->state;
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (rv < SS_SUCCESS) {
 		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
@@ -3772,11 +3772,11 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	drbd_free_sock(mdev);
 
 	/* wait for current activity to cease. */
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	_drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
 	_drbd_wait_ee_list_empty(mdev, &mdev->sync_ee);
 	_drbd_wait_ee_list_empty(mdev, &mdev->read_ee);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	/* We do not have data structures that would allow us to
 	 * get the rs_pending_cnt down to 0 again.
@@ -3828,7 +3828,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	if (mdev->state.role == R_PRIMARY && fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN)
 		drbd_try_outdate_peer_async(mdev);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	os = mdev->state;
 	if (os.conn >= C_UNCONNECTED) {
 		/* Do not restart in case we are C_DISCONNECTING */
@@ -3836,7 +3836,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 		ns.conn = C_UNCONNECTED;
 		rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
 	}
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (os.conn == C_DISCONNECTING) {
 		wait_event(mdev->tconn->net_cnt_wait, atomic_read(&mdev->tconn->net_cnt) == 0);
@@ -4245,14 +4245,14 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
 	struct drbd_request *req;
 	struct bio_and_error m;
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	req = find_request(mdev, root, id, sector, missing_ok, func);
 	if (unlikely(!req)) {
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		return false;
 	}
 	__req_mod(req, what, &m);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	if (m.bio)
 		complete_master_bio(mdev, &m);
@@ -4518,9 +4518,9 @@ int drbd_asender(struct drbd_thread *thi)
 				goto reconnect;
 			/* to avoid race with newly queued ACKs */
 			set_bit(SIGNAL_ASENDER, &mdev->flags);
-			spin_lock_irq(&mdev->req_lock);
+			spin_lock_irq(&mdev->tconn->req_lock);
 			empty = list_empty(&mdev->done_ee);
-			spin_unlock_irq(&mdev->req_lock);
+			spin_unlock_irq(&mdev->tconn->req_lock);
 			/* new ack may have been queued right here,
 			 * but then there is also a signal pending,
 			 * and we start over... */
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index c871ef2..74179f7 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -120,7 +120,7 @@ static void queue_barrier(struct drbd_conf *mdev)
 	if (test_bit(CREATE_BARRIER, &mdev->flags))
 		return;
 
-	b = mdev->newest_tle;
+	b = mdev->tconn->newest_tle;
 	b->w.cb = w_send_barrier;
 	/* inc_ap_pending done here, so we won't
 	 * get imbalanced on connection loss.
@@ -144,7 +144,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	 */
 	if (mdev->state.conn >= C_CONNECTED &&
 	    (s & RQ_NET_SENT) != 0 &&
-	    req->epoch == mdev->newest_tle->br_number)
+	    req->epoch == mdev->tconn->newest_tle->br_number)
 		queue_barrier(mdev);
 
 	/* we need to do the conflict detection stuff,
@@ -516,10 +516,10 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		 * just after it grabs the req_lock */
 		D_ASSERT(test_bit(CREATE_BARRIER, &mdev->flags) == 0);
 
-		req->epoch = mdev->newest_tle->br_number;
+		req->epoch = mdev->tconn->newest_tle->br_number;
 
 		/* increment size of current epoch */
-		mdev->newest_tle->n_writes++;
+		mdev->tconn->newest_tle->n_writes++;
 
 		/* queue work item to send data */
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
@@ -528,7 +528,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		drbd_queue_work(&mdev->tconn->data.work, &req->w);
 
 		/* close the epoch, in case it outgrew the limit */
-		if (mdev->newest_tle->n_writes >= mdev->tconn->net_conf->max_epoch_size)
+		if (mdev->tconn->newest_tle->n_writes >= mdev->tconn->net_conf->max_epoch_size)
 			queue_barrier(mdev);
 
 		break;
@@ -693,7 +693,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 			 * this is bad, because if the connection is lost now,
 			 * we won't be able to clean them up... */
 			dev_err(DEV, "FIXME (BARRIER_ACKED but pending)\n");
-			list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
+			list_move(&req->tl_requests, &mdev->tconn->out_of_sequence_requests);
 		}
 		if ((req->rq_state & RQ_NET_MASK) != 0) {
 			req->rq_state |= RQ_NET_DONE;
@@ -834,7 +834,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
 	 * spinlock, and grabbing the spinlock.
 	 * if we lost that race, we retry.  */
 	if (rw == WRITE && (remote || send_oos) &&
-	    mdev->unused_spare_tle == NULL &&
+	    mdev->tconn->unused_spare_tle == NULL &&
 	    test_bit(CREATE_BARRIER, &mdev->flags)) {
 allocate_barrier:
 		b = kmalloc(sizeof(struct drbd_tl_epoch), GFP_NOIO);
@@ -846,7 +846,7 @@ allocate_barrier:
 	}
 
 	/* GOOD, everything prepared, grab the spin_lock */
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 
 	if (is_susp(mdev->state)) {
 		/* If we got suspended, use the retry mechanism of
@@ -854,7 +854,7 @@ allocate_barrier:
 		   bio. In the next call to drbd_make_request
 		   we sleep in inc_ap_bio() */
 		ret = 1;
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		goto fail_free_complete;
 	}
 
@@ -867,21 +867,21 @@ allocate_barrier:
 			dev_warn(DEV, "lost connection while grabbing the req_lock!\n");
 		if (!(local || remote)) {
 			dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
-			spin_unlock_irq(&mdev->req_lock);
+			spin_unlock_irq(&mdev->tconn->req_lock);
 			goto fail_free_complete;
 		}
 	}
 
-	if (b && mdev->unused_spare_tle == NULL) {
-		mdev->unused_spare_tle = b;
+	if (b && mdev->tconn->unused_spare_tle == NULL) {
+		mdev->tconn->unused_spare_tle = b;
 		b = NULL;
 	}
 	if (rw == WRITE && (remote || send_oos) &&
-	    mdev->unused_spare_tle == NULL &&
+	    mdev->tconn->unused_spare_tle == NULL &&
 	    test_bit(CREATE_BARRIER, &mdev->flags)) {
 		/* someone closed the current epoch
 		 * while we were grabbing the spinlock */
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		goto allocate_barrier;
 	}
 
@@ -899,10 +899,10 @@ allocate_barrier:
 	 * barrier packet.  To get the write ordering right, we only have to
 	 * make sure that, if this is a write request and it triggered a
 	 * barrier packet, this request is queued within the same spinlock. */
-	if ((remote || send_oos) && mdev->unused_spare_tle &&
+	if ((remote || send_oos) && mdev->tconn->unused_spare_tle &&
 	    test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) {
-		_tl_add_barrier(mdev, mdev->unused_spare_tle);
-		mdev->unused_spare_tle = NULL;
+		_tl_add_barrier(mdev, mdev->tconn->unused_spare_tle);
+		mdev->tconn->unused_spare_tle = NULL;
 	} else {
 		D_ASSERT(!(remote && rw == WRITE &&
 			   test_bit(CREATE_BARRIER, &mdev->flags)));
@@ -934,7 +934,7 @@ allocate_barrier:
 	if (rw == WRITE && _req_conflicts(req))
 		goto fail_conflicting;
 
-	list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);
+	list_add_tail(&req->tl_requests, &mdev->tconn->newest_tle->requests);
 
 	/* NOTE remote first: to get the concurrent write detection right,
 	 * we must register the request before start of local IO.  */
@@ -975,7 +975,7 @@ allocate_barrier:
 		}
 	}
 
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	kfree(b); /* if someone else has beaten us to it... */
 
 	if (local) {
@@ -1008,7 +1008,7 @@ fail_conflicting:
 	 * pretend that it was successfully served right now.
 	 */
 	_drbd_end_io_acct(mdev, req);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	if (remote)
 		dec_ap_pending(mdev);
 	/* THINK: do we want to fail it (-EIO), or pretend success?
@@ -1188,10 +1188,10 @@ void request_timer_fn(unsigned long data)
 	if (!et || mdev->state.conn < C_WF_REPORT_PARAMS)
 		return; /* Recurring timer stopped */
 
-	spin_lock_irq(&mdev->req_lock);
-	le = &mdev->oldest_tle->requests;
+	spin_lock_irq(&mdev->tconn->req_lock);
+	le = &mdev->tconn->oldest_tle->requests;
 	if (list_empty(le)) {
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		mod_timer(&mdev->request_timer, jiffies + et);
 		return;
 	}
@@ -1210,5 +1210,5 @@ void request_timer_fn(unsigned long data)
 		mod_timer(&mdev->request_timer, req->start_time + et);
 	}
 
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 }
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 9d75647..4b0858b 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -305,9 +305,9 @@ static inline int req_mod(struct drbd_request *req,
 	struct bio_and_error m;
 	int rv;
 
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	rv = __req_mod(req, what, &m);
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	if (m.bio)
 		complete_master_bio(mdev, &m);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index ec26df3..671251a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -85,14 +85,14 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
 	unsigned long flags = 0;
 	struct drbd_conf *mdev = e->mdev;
 
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	mdev->read_cnt += e->i.size >> 9;
 	list_del(&e->w.list);
 	if (list_empty(&mdev->read_ee))
 		wake_up(&mdev->ee_wait);
 	if (test_bit(__EE_WAS_ERROR, &e->flags))
 		__drbd_chk_io_error(mdev, false);
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	drbd_queue_work(&mdev->tconn->data.work, &e->w);
 	put_ldev(mdev);
@@ -117,7 +117,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
 	block_id = e->block_id;
 
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	mdev->writ_cnt += e->i.size >> 9;
 	list_del(&e->w.list); /* has been on active_ee or sync_ee */
 	list_add_tail(&e->w.list, &mdev->done_ee);
@@ -134,7 +134,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 
 	if (test_bit(__EE_WAS_ERROR, &e->flags))
 		__drbd_chk_io_error(mdev, false);
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	if (block_id == ID_SYNCER)
 		drbd_rs_complete_io(mdev, e_sector);
@@ -220,9 +220,9 @@ void drbd_endio_pri(struct bio *bio, int error)
 	req->private_bio = ERR_PTR(error);
 
 	/* not req_mod(), we need irqsave here! */
-	spin_lock_irqsave(&mdev->req_lock, flags);
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	__req_mod(req, what, &m);
-	spin_unlock_irqrestore(&mdev->req_lock, flags);
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 	if (m.bio)
 		complete_master_bio(mdev, &m);
@@ -236,13 +236,13 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * but try to WRITE the P_DATA_REPLY to the failed location,
 	 * to give the disk the chance to relocate that block */
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (cancel || mdev->state.pdsk != D_UP_TO_DATE) {
 		_req_mod(req, READ_RETRY_REMOTE_CANCELED);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		return 1;
 	}
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	return w_send_read_req(mdev, w, 0);
 }
@@ -359,9 +359,9 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 		goto defer;
 
 	e->w.cb = w_e_send_csum;
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_add(&e->w.list, &mdev->read_ee);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	atomic_add(size >> 9, &mdev->rs_sect_ev);
 	if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
@@ -371,9 +371,9 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 	 * because bio_add_page failed (probably broken lower level driver),
 	 * retry may or may not help.
 	 * If it does not, you may need to force disconnect. */
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	list_del(&e->w.list);
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	drbd_free_ee(mdev, e);
 defer:
@@ -793,7 +793,7 @@ int drbd_resync_finished(struct drbd_conf *mdev)
 
 	ping_peer(mdev);
 
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	os = mdev->state;
 
 	verify_done = (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T);
@@ -882,7 +882,7 @@ int drbd_resync_finished(struct drbd_conf *mdev)
 
 	_drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
 out_unlock:
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	put_ldev(mdev);
 out:
 	mdev->rs_total  = 0;
@@ -907,9 +907,9 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_ent
 		int i = (e->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
 		atomic_add(i, &mdev->pp_in_use_by_net);
 		atomic_sub(i, &mdev->pp_in_use);
-		spin_lock_irq(&mdev->req_lock);
+		spin_lock_irq(&mdev->tconn->req_lock);
 		list_add_tail(&e->w.list, &mdev->net_ee);
-		spin_unlock_irq(&mdev->req_lock);
+		spin_unlock_irq(&mdev->tconn->req_lock);
 		wake_up(&drbd_pp_wait);
 	} else
 		drbd_free_ee(mdev, e);
@@ -1210,10 +1210,10 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * actually, this race was harmless, since we only try to send the
 	 * barrier packet here, and otherwise do nothing with the object.
 	 * but compare with the head of w_clear_epoch */
-	spin_lock_irq(&mdev->req_lock);
+	spin_lock_irq(&mdev->tconn->req_lock);
 	if (w->cb != w_send_barrier || mdev->state.conn < C_CONNECTED)
 		cancel = 1;
-	spin_unlock_irq(&mdev->req_lock);
+	spin_unlock_irq(&mdev->tconn->req_lock);
 	if (cancel)
 		return 1;
 
-- 
1.7.4.1


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

* [PATCH 035/118] drbd: moved crypto transformations and friends from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (33 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 034/118] drbd: moved req_lock and transfer log from mdev " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 036/118] drbd: Made drbd_flush_workqueue() to take a tconn instead of an mdev Philipp Reisner
                   ` (84 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

sed -i \
       -e 's/mdev->cram_hmac_tfm/mdev->tconn->cram_hmac_tfm/g' \
       -e 's/mdev->integrity_w_tfm/mdev->tconn->integrity_w_tfm/g' \
       -e 's/mdev->integrity_r_tfm/mdev->tconn->integrity_r_tfm/g' \
       -e 's/mdev->int_dig_out/mdev->tconn->int_dig_out/g' \
       -e 's/mdev->int_dig_in/mdev->tconn->int_dig_in/g' \
       -e 's/mdev->int_dig_vv/mdev->tconn->int_dig_vv/g' \
       *.[ch]

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   13 ++++++-----
 drivers/block/drbd/drbd_main.c     |   42 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_nl.c       |   24 ++++++++++----------
 drivers/block/drbd/drbd_receiver.c |   32 +++++++++++++-------------
 4 files changed, 56 insertions(+), 55 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0e9debe..65f0e78 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -982,6 +982,13 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct drbd_tl_epoch *oldest_tle;
 	struct list_head out_of_sequence_requests;
 
+	struct crypto_hash *cram_hmac_tfm;
+	struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */
+	struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
+	void *int_dig_out;
+	void *int_dig_in;
+	void *int_dig_vv;
+
 	struct drbd_thread receiver;
 	struct drbd_thread worker;
 	struct drbd_thread asender;
@@ -1114,12 +1121,6 @@ struct drbd_conf {
 	unsigned int al_tr_number;
 	int al_tr_cycle;
 	int al_tr_pos;   /* position of the next transaction in the journal */
-	struct crypto_hash *cram_hmac_tfm;
-	struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */
-	struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
-	void *int_dig_out;
-	void *int_dig_in;
-	void *int_dig_vv;
 	wait_queue_head_t seq_wait;
 	atomic_t packet_seq;
 	unsigned int peer_seq;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c063cd5..699f639 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2404,8 +2404,8 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
 int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
 		     struct p_data *dp, int data_size)
 {
-	data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
-		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
+	data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
+		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 	return _drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size),
 			      dp->block_id);
 }
@@ -2670,8 +2670,8 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	if (!drbd_get_data_sock(mdev))
 		return 0;
 
-	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
-		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
+		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
 	if (req->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
 		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
@@ -2701,8 +2701,8 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	ok = (sizeof(p) ==
 		drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
 	if (ok && dgs) {
-		dgb = mdev->int_dig_out;
-		drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb);
+		dgb = mdev->tconn->int_dig_out;
+		drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, dgb);
 		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok) {
@@ -2727,8 +2727,8 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 			/* 64 byte, 512 bit, is the largest digest size
 			 * currently supported in kernel crypto. */
 			unsigned char digest[64];
-			drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, digest);
-			if (memcmp(mdev->int_dig_out, digest, dgs)) {
+			drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, digest);
+			if (memcmp(mdev->tconn->int_dig_out, 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);
@@ -2755,8 +2755,8 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 	void *dgb;
 	int dgs;
 
-	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
-		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
+		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
 	if (e->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
 		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
@@ -2783,8 +2783,8 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 
 	ok = sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
 	if (ok && dgs) {
-		dgb = mdev->int_dig_out;
-		drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb);
+		dgb = mdev->tconn->int_dig_out;
+		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, e, dgb);
 		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok)
@@ -3276,9 +3276,9 @@ static void drbd_delete_device(unsigned int minor)
 	kfree(mdev->p_uuid);
 	/* mdev->p_uuid = NULL; */
 
-	kfree(mdev->int_dig_out);
-	kfree(mdev->int_dig_in);
-	kfree(mdev->int_dig_vv);
+	kfree(mdev->tconn->int_dig_out);
+	kfree(mdev->tconn->int_dig_in);
+	kfree(mdev->tconn->int_dig_vv);
 
 	/* cleanup the rest that has been
 	 * allocated from drbd_new_device
@@ -3629,12 +3629,12 @@ void drbd_free_resources(struct drbd_conf *mdev)
 	mdev->csums_tfm = NULL;
 	crypto_free_hash(mdev->verify_tfm);
 	mdev->verify_tfm = NULL;
-	crypto_free_hash(mdev->cram_hmac_tfm);
-	mdev->cram_hmac_tfm = NULL;
-	crypto_free_hash(mdev->integrity_w_tfm);
-	mdev->integrity_w_tfm = NULL;
-	crypto_free_hash(mdev->integrity_r_tfm);
-	mdev->integrity_r_tfm = NULL;
+	crypto_free_hash(mdev->tconn->cram_hmac_tfm);
+	mdev->tconn->cram_hmac_tfm = NULL;
+	crypto_free_hash(mdev->tconn->integrity_w_tfm);
+	mdev->tconn->integrity_w_tfm = NULL;
+	crypto_free_hash(mdev->tconn->integrity_r_tfm);
+	mdev->tconn->integrity_r_tfm = NULL;
 
 	drbd_free_sock(mdev);
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 4eaf81a..0836808 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1532,21 +1532,21 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 	mdev->send_cnt = 0;
 	mdev->recv_cnt = 0;
 
-	crypto_free_hash(mdev->cram_hmac_tfm);
-	mdev->cram_hmac_tfm = tfm;
+	crypto_free_hash(mdev->tconn->cram_hmac_tfm);
+	mdev->tconn->cram_hmac_tfm = tfm;
 
-	crypto_free_hash(mdev->integrity_w_tfm);
-	mdev->integrity_w_tfm = integrity_w_tfm;
+	crypto_free_hash(mdev->tconn->integrity_w_tfm);
+	mdev->tconn->integrity_w_tfm = integrity_w_tfm;
 
-	crypto_free_hash(mdev->integrity_r_tfm);
-	mdev->integrity_r_tfm = integrity_r_tfm;
+	crypto_free_hash(mdev->tconn->integrity_r_tfm);
+	mdev->tconn->integrity_r_tfm = integrity_r_tfm;
 
-	kfree(mdev->int_dig_out);
-	kfree(mdev->int_dig_in);
-	kfree(mdev->int_dig_vv);
-	mdev->int_dig_out=int_dig_out;
-	mdev->int_dig_in=int_dig_in;
-	mdev->int_dig_vv=int_dig_vv;
+	kfree(mdev->tconn->int_dig_out);
+	kfree(mdev->tconn->int_dig_in);
+	kfree(mdev->tconn->int_dig_vv);
+	mdev->tconn->int_dig_out=int_dig_out;
+	mdev->tconn->int_dig_in=int_dig_in;
+	mdev->tconn->int_dig_vv=int_dig_vv;
 	retcode = _drbd_set_state(_NS(mdev, conn, C_UNCONNECTED), CS_VERBOSE, NULL);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index af968a0b..4b37010 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -880,7 +880,7 @@ retry:
 	if (h <= 0)
 		return h;
 
-	if (mdev->cram_hmac_tfm) {
+	if (mdev->tconn->cram_hmac_tfm) {
 		/* drbd_request_state(mdev, NS(conn, WFAuth)); */
 		switch (drbd_do_auth(mdev)) {
 		case -1:
@@ -1240,12 +1240,12 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __
 	struct drbd_epoch_entry *e;
 	struct page *page;
 	int dgs, ds, rr;
-	void *dig_in = mdev->int_dig_in;
-	void *dig_vv = mdev->int_dig_vv;
+	void *dig_in = mdev->tconn->int_dig_in;
+	void *dig_vv = mdev->tconn->int_dig_vv;
 	unsigned long *data;
 
-	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
-		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
+		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 
 	if (dgs) {
 		rr = drbd_recv(mdev, dig_in, dgs);
@@ -1306,7 +1306,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __
 	}
 
 	if (dgs) {
-		drbd_csum_ee(mdev, mdev->integrity_r_tfm, e, dig_vv);
+		drbd_csum_ee(mdev, mdev->tconn->integrity_r_tfm, e, dig_vv);
 		if (memcmp(dig_in, dig_vv, dgs)) {
 			dev_err(DEV, "Digest integrity check FAILED: %llus +%u\n",
 				(unsigned long long)sector, data_size);
@@ -1358,11 +1358,11 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 	struct bio_vec *bvec;
 	struct bio *bio;
 	int dgs, rr, i, expect;
-	void *dig_in = mdev->int_dig_in;
-	void *dig_vv = mdev->int_dig_vv;
+	void *dig_in = mdev->tconn->int_dig_in;
+	void *dig_vv = mdev->tconn->int_dig_vv;
 
-	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
-		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
+	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
+		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 
 	if (dgs) {
 		rr = drbd_recv(mdev, dig_in, dgs);
@@ -1401,7 +1401,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 	}
 
 	if (dgs) {
-		drbd_csum_bio(mdev, mdev->integrity_r_tfm, bio, dig_vv);
+		drbd_csum_bio(mdev, mdev->tconn->integrity_r_tfm, bio, dig_vv);
 		if (memcmp(dig_in, dig_vv, dgs)) {
 			dev_err(DEV, "Digest integrity check FAILED. Broken NICs?\n");
 			return 0;
@@ -3841,8 +3841,8 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	if (os.conn == C_DISCONNECTING) {
 		wait_event(mdev->tconn->net_cnt_wait, atomic_read(&mdev->tconn->net_cnt) == 0);
 
-		crypto_free_hash(mdev->cram_hmac_tfm);
-		mdev->cram_hmac_tfm = NULL;
+		crypto_free_hash(mdev->tconn->cram_hmac_tfm);
+		mdev->tconn->cram_hmac_tfm = NULL;
 
 		kfree(mdev->tconn->net_conf);
 		mdev->tconn->net_conf = NULL;
@@ -4012,10 +4012,10 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	unsigned int length;
 	int rv;
 
-	desc.tfm = mdev->cram_hmac_tfm;
+	desc.tfm = mdev->tconn->cram_hmac_tfm;
 	desc.flags = 0;
 
-	rv = crypto_hash_setkey(mdev->cram_hmac_tfm,
+	rv = crypto_hash_setkey(mdev->tconn->cram_hmac_tfm,
 				(u8 *)mdev->tconn->net_conf->shared_secret, key_len);
 	if (rv) {
 		dev_err(DEV, "crypto_hash_setkey() failed with %d\n", rv);
@@ -4062,7 +4062,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 		goto fail;
 	}
 
-	resp_size = crypto_hash_digestsize(mdev->cram_hmac_tfm);
+	resp_size = crypto_hash_digestsize(mdev->tconn->cram_hmac_tfm);
 	response = kmalloc(resp_size, GFP_NOIO);
 	if (response == NULL) {
 		dev_err(DEV, "kmalloc of response failed\n");
-- 
1.7.4.1


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

* [PATCH 036/118] drbd: Made drbd_flush_workqueue() to take a tconn instead of an mdev
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (34 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 035/118] drbd: moved crypto transformations and friends " Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 037/118] drbd: Preparing to use p_header96 for all packets Philipp Reisner
                   ` (83 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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_nl.c       |    6 +++---
 drivers/block/drbd/drbd_receiver.c |    6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 65f0e78..75c760f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1609,7 +1609,7 @@ extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev,
 		struct list_head *head);
 extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled);
 extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed);
-extern void drbd_flush_workqueue(struct drbd_conf *mdev);
+extern void drbd_flush_workqueue(struct drbd_tconn *tconn);
 
 /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to
  * mess with get_fs/set_fs, we know we are KERNEL_DS always. */
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 0836808..8b8894e 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -876,7 +876,7 @@ static void drbd_reconfig_start(struct drbd_conf *mdev)
 	wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
 	wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
 	drbd_thread_start(&mdev->tconn->worker);
-	drbd_flush_workqueue(mdev);
+	drbd_flush_workqueue(mdev->tconn);
 }
 
 /* if still unconfigured, stops worker again.
@@ -1076,7 +1076,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 	/* also wait for the last barrier ack. */
 	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || is_susp(mdev->state));
 	/* and for any other previously queued work */
-	drbd_flush_workqueue(mdev);
+	drbd_flush_workqueue(mdev->tconn);
 
 	rv = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
 	retcode = rv;  /* FIXME: Type mismatch. */
@@ -1520,7 +1520,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		}
 	}
 
-	drbd_flush_workqueue(mdev);
+	drbd_flush_workqueue(mdev->tconn);
 	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->tconn->net_conf != NULL) {
 		retcode = ERR_NET_CONFIGURED;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 4b37010..fbf9382 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3747,13 +3747,13 @@ static void drbdd(struct drbd_conf *mdev)
 	drbd_md_sync(mdev);
 }
 
-void drbd_flush_workqueue(struct drbd_conf *mdev)
+void drbd_flush_workqueue(struct drbd_tconn *tconn)
 {
 	struct drbd_wq_barrier barr;
 
 	barr.w.cb = w_prev_work_done;
 	init_completion(&barr.done);
-	drbd_queue_work(&mdev->tconn->data.work, &barr.w);
+	drbd_queue_work(&tconn->data.work, &barr.w);
 	wait_for_completion(&barr.done);
 }
 
@@ -3803,7 +3803,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	/* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
 	 * w_make_resync_request etc. which may still be on the worker queue
 	 * to be "canceled" */
-	drbd_flush_workqueue(mdev);
+	drbd_flush_workqueue(mdev->tconn);
 
 	/* This also does reclaim_net_ee().  If we do this too early, we might
 	 * miss some resync ee and pages.*/
-- 
1.7.4.1


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

* [PATCH 037/118] drbd: Preparing to use p_header96 for all packets
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (35 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 036/118] drbd: Made drbd_flush_workqueue() to take a tconn instead of an mdev Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 038/118] drbd: Replaced all p_header80 with a generic p_header Philipp Reisner
                   ` (82 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

recv_bm_rle_bits() should not make any assumptions abou the layout
of the packet header

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index fbf9382..12fdd73 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3393,7 +3393,8 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
 static int
 recv_bm_rle_bits(struct drbd_conf *mdev,
 		struct p_compressed_bm *p,
-		struct bm_xfer_ctx *c)
+		 struct bm_xfer_ctx *c,
+		 unsigned int len)
 {
 	struct bitstream bs;
 	u64 look_ahead;
@@ -3401,7 +3402,6 @@ recv_bm_rle_bits(struct drbd_conf *mdev,
 	u64 tmp;
 	unsigned long s = c->bit_offset;
 	unsigned long e;
-	int len = be16_to_cpu(p->head.length) - (sizeof(*p) - sizeof(p->head));
 	int toggle = DCBP_get_start(p);
 	int have;
 	int bits;
@@ -3458,10 +3458,11 @@ recv_bm_rle_bits(struct drbd_conf *mdev,
 static int
 decode_bitmap_c(struct drbd_conf *mdev,
 		struct p_compressed_bm *p,
-		struct bm_xfer_ctx *c)
+		struct bm_xfer_ctx *c,
+		unsigned int len)
 {
 	if (DCBP_get_code(p) == RLE_VLI_Bits)
-		return recv_bm_rle_bits(mdev, p, c);
+		return recv_bm_rle_bits(mdev, p, c, len);
 
 	/* other variants had been implemented for evaluation,
 	 * but have been dropped as this one turned out to be "best"
@@ -3560,7 +3561,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
 				dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size);
 				goto out;
 			}
-			err = decode_bitmap_c(mdev, p, &c);
+			err = decode_bitmap_c(mdev, p, &c, data_size);
 		} else {
 			dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", cmd);
 			goto out;
-- 
1.7.4.1


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

* [PATCH 038/118] drbd: Replaced all p_header80 with a generic p_header
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (36 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 037/118] drbd: Preparing to use p_header96 for all packets Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 039/118] drbd: Use new header layout, and send volume IOs Philipp Reisner
                   ` (81 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 75c760f..9d0ba1f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -338,7 +338,6 @@ struct p_header80 {
 	u32	  magic;
 	u16	  command;
 	u16	  length;	/* bytes of data after this header */
-	u8	  payload[0];
 } __packed;
 
 /* Header for big packets, Used for data packets exceeding 64kB */
@@ -349,9 +348,12 @@ struct p_header95 {
 	u8	  payload[0];
 } __packed;
 
-union p_header {
-	struct p_header80 h80;
-	struct p_header95 h95;
+struct p_header {
+	union {
+		struct p_header80 h80;
+		struct p_header95 h95;
+	};
+	u8	  payload[0];
 };
 
 /*
@@ -380,7 +382,7 @@ union p_header {
 #define DP_DISCARD           64 /* equals REQ_DISCARD */
 
 struct p_data {
-	union p_header head;
+	struct p_header head;
 	u64	    sector;    /* 64 bits sector number */
 	u64	    block_id;  /* to identify the request in protocol B&C */
 	u32	    seq_num;
@@ -396,7 +398,7 @@ struct p_data {
  *   P_DATA_REQUEST, P_RS_DATA_REQUEST
  */
 struct p_block_ack {
-	struct p_header80 head;
+	struct p_header head;
 	u64	    sector;
 	u64	    block_id;
 	u32	    blksize;
@@ -405,7 +407,7 @@ struct p_block_ack {
 
 
 struct p_block_req {
-	struct p_header80 head;
+	struct p_header head;
 	u64 sector;
 	u64 block_id;
 	u32 blksize;
@@ -422,7 +424,7 @@ struct p_block_req {
  */
 
 struct p_handshake {
-	struct p_header80 head;	/* 8 bytes */
+	struct p_header head;	/* Note: You must always use a h80 here */
 	u32 protocol_min;
 	u32 feature_flags;
 	u32 protocol_max;
@@ -437,19 +439,19 @@ struct p_handshake {
 /* 80 bytes, FIXED for the next century */
 
 struct p_barrier {
-	struct p_header80 head;
+	struct p_header head;
 	u32 barrier;	/* barrier number _handle_ only */
 	u32 pad;	/* to multiple of 8 Byte */
 } __packed;
 
 struct p_barrier_ack {
-	struct p_header80 head;
+	struct p_header head;
 	u32 barrier;
 	u32 set_size;
 } __packed;
 
 struct p_rs_param {
-	struct p_header80 head;
+	struct p_header head;
 	u32 rate;
 
 	      /* Since protocol version 88 and higher. */
@@ -457,7 +459,7 @@ struct p_rs_param {
 } __packed;
 
 struct p_rs_param_89 {
-	struct p_header80 head;
+	struct p_header head;
 	u32 rate;
         /* protocol version 89: */
 	char verify_alg[SHARED_SECRET_MAX];
@@ -465,7 +467,7 @@ struct p_rs_param_89 {
 } __packed;
 
 struct p_rs_param_95 {
-	struct p_header80 head;
+	struct p_header head;
 	u32 rate;
 	char verify_alg[SHARED_SECRET_MAX];
 	char csums_alg[SHARED_SECRET_MAX];
@@ -481,7 +483,7 @@ enum drbd_conn_flags {
 };
 
 struct p_protocol {
-	struct p_header80 head;
+	struct p_header head;
 	u32 protocol;
 	u32 after_sb_0p;
 	u32 after_sb_1p;
@@ -495,17 +497,17 @@ struct p_protocol {
 } __packed;
 
 struct p_uuids {
-	struct p_header80 head;
+	struct p_header head;
 	u64 uuid[UI_EXTENDED_SIZE];
 } __packed;
 
 struct p_rs_uuid {
-	struct p_header80 head;
+	struct p_header head;
 	u64	    uuid;
 } __packed;
 
 struct p_sizes {
-	struct p_header80 head;
+	struct p_header head;
 	u64	    d_size;  /* size of disk */
 	u64	    u_size;  /* user requested size */
 	u64	    c_size;  /* current exported size */
@@ -515,18 +517,18 @@ struct p_sizes {
 } __packed;
 
 struct p_state {
-	struct p_header80 head;
+	struct p_header head;
 	u32	    state;
 } __packed;
 
 struct p_req_state {
-	struct p_header80 head;
+	struct p_header head;
 	u32	    mask;
 	u32	    val;
 } __packed;
 
 struct p_req_state_reply {
-	struct p_header80 head;
+	struct p_header head;
 	u32	    retcode;
 } __packed;
 
@@ -541,14 +543,14 @@ struct p_drbd06_param {
 } __packed;
 
 struct p_discard {
-	struct p_header80 head;
+	struct p_header head;
 	u64	    block_id;
 	u32	    seq_num;
 	u32	    pad;
 } __packed;
 
 struct p_block_desc {
-	struct p_header80 head;
+	struct p_header head;
 	u64 sector;
 	u32 blksize;
 	u32 pad;	/* to multiple of 8 Byte */
@@ -564,7 +566,7 @@ enum drbd_bitmap_code {
 };
 
 struct p_compressed_bm {
-	struct p_header80 head;
+	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
@@ -576,7 +578,7 @@ struct p_compressed_bm {
 } __packed;
 
 struct p_delay_probe93 {
-	struct p_header80 head;
+	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;
@@ -625,7 +627,7 @@ DCBP_set_pad_bits(struct p_compressed_bm *p, int n)
  * so we need to use the fixed size 4KiB page size
  * most architectures have used for a long time.
  */
-#define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header80))
+#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)
@@ -634,7 +636,7 @@ DCBP_set_pad_bits(struct p_compressed_bm *p, int n)
 #endif
 
 union p_polymorph {
-        union p_header           header;
+        struct p_header           header;
         struct p_handshake       handshake;
         struct p_data            data;
         struct p_block_ack       block_ack;
@@ -1245,12 +1247,12 @@ extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_f
 extern int _drbd_send_state(struct drbd_conf *mdev);
 extern int drbd_send_state(struct drbd_conf *mdev);
 extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
-			enum drbd_packets cmd, struct p_header80 *h,
+			enum drbd_packets cmd, struct p_header *h,
 			size_t size, unsigned msg_flags);
 #define USE_DATA_SOCKET 1
 #define USE_META_SOCKET 0
 extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
-			enum drbd_packets cmd, struct p_header80 *h,
+			enum drbd_packets cmd, struct p_header *h,
 			size_t size);
 extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd,
 			char *data, size_t size);
@@ -2019,19 +2021,19 @@ static inline void request_ping(struct drbd_conf *mdev)
 static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
 	enum drbd_packets cmd)
 {
-	struct p_header80 h;
+	struct p_header h;
 	return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h));
 }
 
 static inline int drbd_send_ping(struct drbd_conf *mdev)
 {
-	struct p_header80 h;
+	struct p_header h;
 	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING, &h, sizeof(h));
 }
 
 static inline int drbd_send_ping_ack(struct drbd_conf *mdev)
 {
-	struct p_header80 h;
+	struct p_header h;
 	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h));
 }
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 699f639..55ce48e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1822,9 +1822,10 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 
 /* the appropriate socket mutex must be held already */
 int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
-			  enum drbd_packets cmd, struct p_header80 *h,
+			  enum drbd_packets cmd, struct p_header *hg,
 			  size_t size, unsigned msg_flags)
 {
+	struct p_header80 *h = (struct p_header80 *)hg;
 	int sent, ok;
 
 	if (!expect(h))
@@ -1849,7 +1850,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
  * when we hold the appropriate socket mutex.
  */
 int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
-		  enum drbd_packets cmd, struct p_header80 *h, size_t size)
+		  enum drbd_packets cmd, struct p_header *h, size_t size)
 {
 	int ok = 0;
 	struct socket *sock;
@@ -1983,8 +1984,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	if (mdev->tconn->agreed_pro_version >= 87)
 		strcpy(p->integrity_alg, mdev->tconn->net_conf->integrity_alg);
 
-	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL,
-			   (struct p_header80 *)p, size);
+	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL, &p->head, size);
 	kfree(p);
 	return rv;
 }
@@ -2009,8 +2009,7 @@ int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags)
 
 	put_ldev(mdev);
 
-	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_UUIDS,
-			     (struct p_header80 *)&p, sizeof(p));
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_UUIDS, &p.head, sizeof(p));
 }
 
 int drbd_send_uuids(struct drbd_conf *mdev)
@@ -2054,8 +2053,7 @@ int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev)
 	drbd_md_sync(mdev);
 	p.uuid = cpu_to_be64(uuid);
 
-	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SYNC_UUID,
-			     (struct p_header80 *)&p, sizeof(p));
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SYNC_UUID, &p.head, sizeof(p));
 }
 
 int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags)
@@ -2087,8 +2085,7 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl
 	p.queue_order_type = cpu_to_be16(q_order_type);
 	p.dds_flags = cpu_to_be16(flags);
 
-	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SIZES,
-			   (struct p_header80 *)&p, sizeof(p));
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SIZES, &p.head, sizeof(p));
 	return ok;
 }
 
@@ -2112,8 +2109,7 @@ int drbd_send_state(struct drbd_conf *mdev)
 	sock = mdev->tconn->data.socket;
 
 	if (likely(sock != NULL)) {
-		ok = _drbd_send_cmd(mdev, sock, P_STATE,
-				    (struct p_header80 *)&p, sizeof(p), 0);
+		ok = _drbd_send_cmd(mdev, sock, P_STATE, &p.head, sizeof(p), 0);
 	}
 
 	mutex_unlock(&mdev->tconn->data.mutex);
@@ -2130,8 +2126,7 @@ int drbd_send_state_req(struct drbd_conf *mdev,
 	p.mask    = cpu_to_be32(mask.i);
 	p.val     = cpu_to_be32(val.i);
 
-	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_STATE_CHG_REQ,
-			     (struct p_header80 *)&p, sizeof(p));
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_STATE_CHG_REQ, &p.head, sizeof(p));
 }
 
 int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode)
@@ -2140,8 +2135,7 @@ int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode)
 
 	p.retcode    = cpu_to_be32(retcode);
 
-	return drbd_send_cmd(mdev, USE_META_SOCKET, P_STATE_CHG_REPLY,
-			     (struct p_header80 *)&p, sizeof(p));
+	return drbd_send_cmd(mdev, USE_META_SOCKET, P_STATE_CHG_REPLY, &p.head, sizeof(p));
 }
 
 int fill_bitmap_rle_bits(struct drbd_conf *mdev,
@@ -2246,7 +2240,7 @@ int fill_bitmap_rle_bits(struct drbd_conf *mdev,
  */
 static int
 send_bitmap_rle_or_plain(struct drbd_conf *mdev,
-			 struct p_header80 *h, struct bm_xfer_ctx *c)
+			 struct p_header *h, struct bm_xfer_ctx *c)
 {
 	struct p_compressed_bm *p = (void*)h;
 	unsigned long num_words;
@@ -2300,7 +2294,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev,
 int _drbd_send_bitmap(struct drbd_conf *mdev)
 {
 	struct bm_xfer_ctx c;
-	struct p_header80 *p;
+	struct p_header *p;
 	int err;
 
 	if (!expect(mdev->bitmap))
@@ -2308,7 +2302,7 @@ int _drbd_send_bitmap(struct drbd_conf *mdev)
 
 	/* maybe we should use some per thread scratch page,
 	 * and allocate that during initial device creation? */
-	p = (struct p_header80 *) __get_free_page(GFP_NOIO);
+	p = (struct p_header *) __get_free_page(GFP_NOIO);
 	if (!p) {
 		dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
 		return false;
@@ -2365,8 +2359,7 @@ int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
 
 	if (mdev->state.conn < C_CONNECTED)
 		return false;
-	ok = drbd_send_cmd(mdev, USE_META_SOCKET, P_BARRIER_ACK,
-			(struct p_header80 *)&p, sizeof(p));
+	ok = drbd_send_cmd(mdev, USE_META_SOCKET, P_BARRIER_ACK, &p.head, sizeof(p));
 	return ok;
 }
 
@@ -2393,8 +2386,7 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
 
 	if (!mdev->tconn->meta.socket || mdev->state.conn < C_CONNECTED)
 		return false;
-	ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd,
-				(struct p_header80 *)&p, sizeof(p));
+	ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd, &p.head, sizeof(p));
 	return ok;
 }
 
@@ -2452,8 +2444,7 @@ int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
 	p.block_id = block_id;
 	p.blksize  = cpu_to_be32(size);
 
-	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd,
-				(struct p_header80 *)&p, sizeof(p));
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &p.head, sizeof(p));
 	return ok;
 }
 
@@ -2469,9 +2460,9 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev,
 	p.block_id = ID_SYNCER /* unused */;
 	p.blksize  = cpu_to_be32(size);
 
-	p.head.magic   = cpu_to_be32(DRBD_MAGIC);
-	p.head.command = cpu_to_be16(cmd);
-	p.head.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + digest_size);
+	p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
+	p.head.h80.command = cpu_to_be16(cmd);
+	p.head.h80.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + digest_size);
 
 	mutex_lock(&mdev->tconn->data.mutex);
 
@@ -2492,8 +2483,7 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size)
 	p.block_id = ID_SYNCER /* unused */;
 	p.blksize  = cpu_to_be32(size);
 
-	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OV_REQUEST,
-			   (struct p_header80 *)&p, sizeof(p));
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OV_REQUEST, &p.head, sizeof(p));
 	return ok;
 }
 
@@ -2677,12 +2667,12 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
 		p.head.h80.command = cpu_to_be16(P_DATA);
 		p.head.h80.length  =
-			cpu_to_be16(sizeof(p) - sizeof(union p_header) + dgs + req->i.size);
+			cpu_to_be16(sizeof(p) - sizeof(struct p_header) + dgs + req->i.size);
 	} else {
 		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 		p.head.h95.command = cpu_to_be16(P_DATA);
 		p.head.h95.length  =
-			cpu_to_be32(sizeof(p) - sizeof(union p_header) + dgs + req->i.size);
+			cpu_to_be32(sizeof(p) - sizeof(struct p_header) + dgs + req->i.size);
 	}
 
 	p.sector   = cpu_to_be64(req->i.sector);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 12fdd73..9393fe4 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -700,7 +700,7 @@ out:
 static int drbd_send_fp(struct drbd_conf *mdev,
 	struct socket *sock, enum drbd_packets cmd)
 {
-	struct p_header80 *h = &mdev->tconn->data.sbuf.header.h80;
+	struct p_header *h = &mdev->tconn->data.sbuf.header;
 
 	return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0);
 }
@@ -925,7 +925,7 @@ out_release_sockets:
 
 static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
 {
-	union p_header *h = &mdev->tconn->data.rbuf.header;
+	struct p_header *h = &mdev->tconn->data.rbuf.header;
 	int r;
 
 	r = drbd_recv(mdev, h, sizeof(*h));
@@ -3477,7 +3477,7 @@ 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_header80) *
+	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];
@@ -3699,7 +3699,7 @@ static struct data_cmd drbd_cmd_handler[] = {
 
 static void drbdd(struct drbd_conf *mdev)
 {
-	union p_header *header = &mdev->tconn->data.rbuf.header;
+	struct p_header *header = &mdev->tconn->data.rbuf.header;
 	unsigned int packet_size;
 	enum drbd_packets cmd;
 	size_t shs; /* sub header size */
@@ -3715,14 +3715,14 @@ static void drbdd(struct drbd_conf *mdev)
 			goto err_out;
 		}
 
-		shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header);
+		shs = drbd_cmd_handler[cmd].pkt_size - sizeof(struct p_header);
 		if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
 			dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
 			goto err_out;
 		}
 
 		if (shs) {
-			rv = drbd_recv(mdev, &header->h80.payload, shs);
+			rv = drbd_recv(mdev, &header->payload, shs);
 			if (unlikely(rv != shs)) {
 				if (!signal_pending(current))
 					dev_warn(DEV, "short read while reading sub header: rv=%d\n", rv);
@@ -3909,8 +3909,8 @@ static int drbd_send_handshake(struct drbd_conf *mdev)
 	memset(p, 0, sizeof(*p));
 	p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
 	p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
-	ok = _drbd_send_cmd( mdev, mdev->tconn->data.socket, P_HAND_SHAKE,
-			     (struct p_header80 *)p, sizeof(*p), 0 );
+	ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_HAND_SHAKE,
+			    &p->head, sizeof(*p), 0 );
 	mutex_unlock(&mdev->tconn->data.mutex);
 	return ok;
 }
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 671251a..afad8ea 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1224,7 +1224,7 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * dec_ap_pending will be done in got_BarrierAck
 	 * or (on connection loss) in w_clear_epoch.  */
 	ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_BARRIER,
-				(struct p_header80 *)p, sizeof(*p), 0);
+			    &p->head, sizeof(*p), 0);
 	drbd_put_data_sock(mdev);
 
 	return ok;
-- 
1.7.4.1


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

* [PATCH 039/118] drbd: Use new header layout, and send volume IOs
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (37 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 038/118] drbd: Replaced all p_header80 with a generic p_header Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 040/118] drbd: Implemented receiving of new style packets on meta socket Philipp Reisner
                   ` (80 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

The new header layout will only be used if the peer supports
it of course.

For the first packet and the handshake packet the old (h80)
layout is used for compatibility reasons.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9d0ba1f..4c5d143 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -344,8 +344,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. */
-	u8	  payload[0];
+	u32	  vol_n_len;	/* big endian: high byte = volume; remaining 24 bit = length */
 } __packed;
 
 struct p_header {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 55ce48e..f464cfa 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1820,12 +1820,36 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 }
 #endif
 
+static void prepare_header80(struct drbd_conf *mdev, struct p_header80 *h,
+			     enum drbd_packets cmd, int size)
+{
+	h->magic   = cpu_to_be32(DRBD_MAGIC);
+	h->command = cpu_to_be16(cmd);
+	h->length  = cpu_to_be16(size);
+}
+
+static void prepare_header95(struct drbd_conf *mdev, struct p_header95 *h,
+			     enum drbd_packets cmd, int size)
+{
+	h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
+	h->command = cpu_to_be16(cmd);
+	h->vol_n_len = cpu_to_be32(mdev->vnr << 24 | size);
+}
+
+static void prepare_header(struct drbd_conf *mdev, struct p_header *h,
+			   enum drbd_packets cmd, int size)
+{
+	if (mdev->tconn->agreed_pro_version >= 100 || size > DRBD_MAX_SIZE_H80_PACKET)
+		prepare_header95(mdev, &h->h95, cmd, size);
+	else
+		prepare_header80(mdev, &h->h80, cmd, size);
+}
+
 /* the appropriate socket mutex must be held already */
 int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
-			  enum drbd_packets cmd, struct p_header *hg,
+			  enum drbd_packets cmd, struct p_header *h,
 			  size_t size, unsigned msg_flags)
 {
-	struct p_header80 *h = (struct p_header80 *)hg;
 	int sent, ok;
 
 	if (!expect(h))
@@ -1833,9 +1857,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
 	if (!expect(size))
 		return false;
 
-	h->magic   = cpu_to_be32(DRBD_MAGIC);
-	h->command = cpu_to_be16(cmd);
-	h->length  = cpu_to_be16(size-sizeof(struct p_header80));
+	prepare_header(mdev, h, cmd, size - sizeof(struct p_header));
 
 	sent = drbd_send(mdev, sock, h, size, msg_flags);
 
@@ -1878,12 +1900,10 @@ int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
 		   size_t size)
 {
-	struct p_header80 h;
+	struct p_header h;
 	int ok;
 
-	h.magic   = cpu_to_be32(DRBD_MAGIC);
-	h.command = cpu_to_be16(cmd);
-	h.length  = cpu_to_be16(size);
+	prepare_header(mdev, &h, cmd, size);
 
 	if (!drbd_get_data_sock(mdev))
 		return 0;
@@ -2456,14 +2476,11 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev,
 	int ok;
 	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);
 
-	p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
-	p.head.h80.command = cpu_to_be16(cmd);
-	p.head.h80.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + digest_size);
-
 	mutex_lock(&mdev->tconn->data.mutex);
 
 	ok = (sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), 0));
@@ -2663,22 +2680,10 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
-	if (req->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
-		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
-		p.head.h80.command = cpu_to_be16(P_DATA);
-		p.head.h80.length  =
-			cpu_to_be16(sizeof(p) - sizeof(struct p_header) + dgs + req->i.size);
-	} else {
-		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
-		p.head.h95.command = cpu_to_be16(P_DATA);
-		p.head.h95.length  =
-			cpu_to_be32(sizeof(p) - sizeof(struct p_header) + dgs + req->i.size);
-	}
-
+	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_add_return(1, &mdev->packet_seq));
+	p.seq_num  = cpu_to_be32(req->seq_num = atomic_add_return(1, &mdev->packet_seq));
 
 	dp_flags = bio_flags_to_wire(mdev, req->master_bio->bi_rw);
 
@@ -2748,18 +2753,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
 	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
 		crypto_hash_digestsize(mdev->tconn->integrity_w_tfm) : 0;
 
-	if (e->i.size <= DRBD_MAX_SIZE_H80_PACKET) {
-		p.head.h80.magic   = cpu_to_be32(DRBD_MAGIC);
-		p.head.h80.command = cpu_to_be16(cmd);
-		p.head.h80.length  =
-			cpu_to_be16(sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
-	} else {
-		p.head.h95.magic   = cpu_to_be16(DRBD_MAGIC_BIG);
-		p.head.h95.command = cpu_to_be16(cmd);
-		p.head.h95.length  =
-			cpu_to_be32(sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
-	}
-
+	prepare_header(mdev, &p.head, cmd, sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
 	p.sector   = cpu_to_be64(e->i.sector);
 	p.block_id = e->block_id;
 	/* p.seq_num  = 0;    No sequence numbers here.. */
@@ -3028,7 +3022,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker);
 	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender);
 
-	mdev->tconn->agreed_pro_version = PRO_VERSION_MAX;
+	/* mdev->tconn->agreed_pro_version gets initialized in drbd_connect() */
 	mdev->write_ordering = WO_bdev_flush;
 	mdev->resync_wenr = LC_FREE;
 	mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
@@ -3506,12 +3500,8 @@ int __init drbd_init(void)
 {
 	int err;
 
-	if (sizeof(struct p_handshake) != 80) {
-		printk(KERN_ERR
-		       "drbd: never change the size or layout "
-		       "of the HandShake packet.\n");
-		return -EINVAL;
-	}
+	BUILD_BUG_ON(sizeof(struct p_header80) != sizeof(struct p_header95));
+	BUILD_BUG_ON(sizeof(struct p_handshake) != 80);
 
 	if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) {
 		printk(KERN_ERR
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 9393fe4..e45ed47 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -761,6 +761,9 @@ static int drbd_connect(struct drbd_conf *mdev)
 		return -2;
 
 	clear_bit(DISCARD_CONCURRENT, &mdev->flags);
+	mdev->tconn->agreed_pro_version = 99;
+	/* agreed_pro_version must be smaller than 100 so we send the old
+	   header (h80) in the first packet and in the handshake packet. */
 
 	sock  = NULL;
 	msock = NULL;
@@ -926,6 +929,7 @@ out_release_sockets:
 static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
 {
 	struct p_header *h = &mdev->tconn->data.rbuf.header;
+	u32 vol_n_len;
 	int r;
 
 	r = drbd_recv(mdev, h, sizeof(*h));
@@ -935,12 +939,14 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi
 		return false;
 	}
 
-	if (likely(h->h80.magic == cpu_to_be32(DRBD_MAGIC))) {
+	if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
 		*cmd = be16_to_cpu(h->h80.command);
 		*packet_size = be16_to_cpu(h->h80.length);
 	} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
 		*cmd = be16_to_cpu(h->h95.command);
-		*packet_size = be32_to_cpu(h->h95.length);
+		vol_n_len = be32_to_cpu(h->h95.vol_n_len);
+		*packet_size = vol_n_len & 0x00ffffff;
+		/* vnr = vol_n_len >> 24; */
 	} else {
 		dev_err(DEV, "magic?? on data m: 0x%08x c: %d l: %d\n",
 		    be32_to_cpu(h->h80.magic),
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index d282028..35fc08a 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void);
 #define REL_VERSION "8.3.11"
 #define API_VERSION 88
 #define PRO_VERSION_MIN 86
-#define PRO_VERSION_MAX 96
+#define PRO_VERSION_MAX 100
 
 
 enum drbd_io_error_p {
-- 
1.7.4.1


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

* [PATCH 040/118] drbd: Implemented receiving of new style packets on meta socket
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (38 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 039/118] drbd: Use new header layout, and send volume IOs Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 041/118] drbd: Do not access tconn after it was freed Philipp Reisner
                   ` (79 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Now drbd communication with protocol 100 actually works.
Replaced the remaining p_header80 with p_header where we
no longer know which header it is.

In the places where p_header80 is still in use, it is on
purpose, because we know that it is an old style header
there.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e45ed47..24c906f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -926,18 +926,10 @@ out_release_sockets:
 	return -1;
 }
 
-static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
+static bool decode_header(struct drbd_conf *mdev, struct p_header *h, enum drbd_packets *cmd,
+			  unsigned int *packet_size)
 {
-	struct p_header *h = &mdev->tconn->data.rbuf.header;
 	u32 vol_n_len;
-	int r;
-
-	r = drbd_recv(mdev, h, sizeof(*h));
-	if (unlikely(r != sizeof(*h))) {
-		if (!signal_pending(current))
-			dev_warn(DEV, "short read expecting header on sock: r=%d\n", r);
-		return false;
-	}
 
 	if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
 		*cmd = be16_to_cpu(h->h80.command);
@@ -954,9 +946,25 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi
 		    be16_to_cpu(h->h80.length));
 		return false;
 	}
+	return true;
+}
+
+static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
+{
+	struct p_header *h = &mdev->tconn->data.rbuf.header;
+	int r;
+
+	r = drbd_recv(mdev, h, sizeof(*h));
+	if (unlikely(r != sizeof(*h))) {
+		if (!signal_pending(current))
+			dev_warn(DEV, "short read expecting header on sock: r=%d\n", r);
+		return false;
+	}
+
+	r = decode_header(mdev, h, cmd, packet_size);
 	mdev->tconn->last_received = jiffies;
 
-	return true;
+	return r;
 }
 
 static void drbd_flush(struct drbd_conf *mdev)
@@ -2810,14 +2818,14 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	}
 
 	if (apv <= 88) {
-		header_size = sizeof(struct p_rs_param) - sizeof(struct p_header80);
+		header_size = sizeof(struct p_rs_param) - sizeof(struct p_header);
 		data_size   = packet_size  - header_size;
 	} else if (apv <= 94) {
-		header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header80);
+		header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header);
 		data_size   = packet_size  - header_size;
 		D_ASSERT(data_size == 0);
 	} else {
-		header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header80);
+		header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header);
 		data_size   = packet_size  - header_size;
 		D_ASSERT(data_size == 0);
 	}
@@ -3527,7 +3535,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
 	void *buffer;
 	int err;
 	int ok = false;
-	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
+	struct p_header *h = &mdev->tconn->data.rbuf.header;
 
 	drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
 	/* you are supposed to send additional out-of-sync information
@@ -3574,7 +3582,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
 		}
 
 		c.packets[cmd == P_BITMAP]++;
-		c.bytes[cmd == P_BITMAP] += sizeof(struct p_header80) + data_size;
+		c.bytes[cmd == P_BITMAP] += sizeof(struct p_header) + data_size;
 
 		if (err <= 0) {
 			if (err < 0)
@@ -3673,13 +3681,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_header80), receive_bitmap } ,
-	[P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header80), receive_bitmap } ,
-	[P_UNPLUG_REMOTE]   = { 0, sizeof(struct p_header80), receive_UnplugRemote },
+	[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_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_header80), receive_SyncParam },
-	[P_SYNC_PARAM89]    = { 1, sizeof(struct p_header80), receive_SyncParam },
+	[P_SYNC_PARAM]	    = { 1, sizeof(struct p_header), receive_SyncParam },
+	[P_SYNC_PARAM89]    = { 1, sizeof(struct p_header), 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 },
@@ -4187,9 +4195,9 @@ int drbdd_init(struct drbd_thread *thi)
 
 /* ********* acknowledge sender ******** */
 
-static int got_RqSReply(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_req_state_reply *p = (struct p_req_state_reply *)h;
+	struct p_req_state_reply *p = &mdev->tconn->meta.rbuf.req_state_reply;
 
 	int retcode = be32_to_cpu(p->retcode);
 
@@ -4205,13 +4213,13 @@ static int got_RqSReply(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_Ping(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_Ping(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
 	return drbd_send_ping_ack(mdev);
 
 }
 
-static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_PingAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
 	/* restore idle timeout */
 	mdev->tconn->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
@@ -4221,9 +4229,9 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_IsInSync(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
 	int blksize = be32_to_cpu(p->blksize);
 
@@ -4266,9 +4274,9 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
 	return true;
 }
 
-static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
 	int blksize = be32_to_cpu(p->blksize);
 	enum drbd_req_event what;
@@ -4280,7 +4288,7 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 		dec_rs_pending(mdev);
 		return true;
 	}
-	switch (be16_to_cpu(h->command)) {
+	switch (cmd) {
 	case P_RS_WRITE_ACK:
 		D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
 		what = WRITE_ACKED_BY_PEER_AND_SIS;
@@ -4307,9 +4315,9 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
 					     what, false);
 }
 
-static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_NegAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
 	int size = be32_to_cpu(p->blksize);
 	bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A ||
@@ -4340,9 +4348,9 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
 
 	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
@@ -4354,11 +4362,11 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
 					     NEG_ACKED, false);
 }
 
-static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
 	sector_t sector;
 	int size;
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 
 	sector = be64_to_cpu(p->sector);
 	size = be32_to_cpu(p->blksize);
@@ -4369,7 +4377,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
 
 	if (get_ldev_if_state(mdev, D_FAILED)) {
 		drbd_rs_complete_io(mdev, sector);
-		switch (be16_to_cpu(h->command)) {
+		switch (cmd) {
 		case P_NEG_RS_DREPLY:
 			drbd_rs_failed_io(mdev, sector, size);
 		case P_RS_CANCEL:
@@ -4385,9 +4393,9 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_barrier_ack *p = (struct p_barrier_ack *)h;
+	struct p_barrier_ack *p = &mdev->tconn->meta.rbuf.barrier_ack;
 
 	tl_release(mdev, p->barrier, be32_to_cpu(p->set_size));
 
@@ -4401,9 +4409,9 @@ static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_OVResult(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
-	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	struct drbd_work *w;
 	sector_t sector;
 	int size;
@@ -4445,14 +4453,14 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h)
 	return true;
 }
 
-static int got_skip(struct drbd_conf *mdev, struct p_header80 *h)
+static int got_skip(struct drbd_conf *mdev, enum drbd_packets cmd)
 {
 	return true;
 }
 
 struct asender_cmd {
 	size_t pkt_size;
-	int (*process)(struct drbd_conf *mdev, struct p_header80 *h);
+	int (*process)(struct drbd_conf *mdev, enum drbd_packets cmd);
 };
 
 static struct asender_cmd *get_asender_cmd(int cmd)
@@ -4461,8 +4469,8 @@ static struct asender_cmd *get_asender_cmd(int cmd)
 		/* anything missing from this table is in
 		 * the drbd_cmd_handler (drbd_default_handler) table,
 		 * see the beginning of drbdd() */
-	[P_PING]	    = { sizeof(struct p_header80), got_Ping },
-	[P_PING_ACK]	    = { sizeof(struct p_header80), got_PingAck },
+	[P_PING]	    = { sizeof(struct p_header), got_Ping },
+	[P_PING_ACK]	    = { sizeof(struct p_header), 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 },
@@ -4486,15 +4494,16 @@ static struct asender_cmd *get_asender_cmd(int cmd)
 int drbd_asender(struct drbd_thread *thi)
 {
 	struct drbd_conf *mdev = thi->mdev;
-	struct p_header80 *h = &mdev->tconn->meta.rbuf.header.h80;
+	struct p_header *h = &mdev->tconn->meta.rbuf.header;
 	struct asender_cmd *cmd = NULL;
 
-	int rv, len;
+	int rv;
 	void *buf    = h;
 	int received = 0;
-	int expect   = sizeof(struct p_header80);
-	int empty;
+	int expect   = sizeof(struct p_header);
 	int ping_timeout_active = 0;
+	int empty, pkt_size;
+	enum drbd_packets cmd_nr;
 
 	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
 
@@ -4584,30 +4593,25 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (unlikely(h->magic != cpu_to_be32(DRBD_MAGIC))) {
-				dev_err(DEV, "magic?? on meta m: 0x%08x c: %d l: %d\n",
-				    be32_to_cpu(h->magic),
-				    be16_to_cpu(h->command),
-				    be16_to_cpu(h->length));
+			if (!decode_header(mdev, h, &cmd_nr, &pkt_size))
 				goto reconnect;
-			}
-			cmd = get_asender_cmd(be16_to_cpu(h->command));
-			len = be16_to_cpu(h->length);
+			cmd = get_asender_cmd(cmd_nr);
 			if (unlikely(cmd == NULL)) {
-				dev_err(DEV, "unknown command?? on meta m: 0x%08x c: %d l: %d\n",
-				    be32_to_cpu(h->magic),
-				    be16_to_cpu(h->command),
-				    be16_to_cpu(h->length));
+				dev_err(DEV, "unknown command %d on meta (l: %d)\n",
+					cmd_nr, pkt_size);
 				goto disconnect;
 			}
 			expect = cmd->pkt_size;
-			if (!expect(len == expect - sizeof(struct p_header80)))
+			if (pkt_size != expect - sizeof(struct p_header)) {
+				dev_err(DEV, "Wrong packet size on meta (c: %d, l: %d)\n",
+					cmd_nr, pkt_size);
 				goto reconnect;
+			}
 		}
 		if (received == expect) {
 			mdev->tconn->last_received = jiffies;
 			D_ASSERT(cmd != NULL);
-			if (!cmd->process(mdev, h))
+			if (!cmd->process(mdev, cmd_nr))
 				goto reconnect;
 
 			/* the idle_timeout (ping-int)
@@ -4617,7 +4621,7 @@ int drbd_asender(struct drbd_thread *thi)
 
 			buf	 = h;
 			received = 0;
-			expect	 = sizeof(struct p_header80);
+			expect	 = sizeof(struct p_header);
 			cmd	 = NULL;
 		}
 	}
-- 
1.7.4.1


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

* [PATCH 041/118] drbd: Do not access tconn after it was freed
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (39 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 040/118] drbd: Implemented receiving of new style packets on meta socket Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 042/118] drbd: Move cmdname() out of drbd_int.h Philipp Reisner
                   ` (78 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f464cfa..a9dea6d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3260,10 +3260,6 @@ static void drbd_delete_device(unsigned int minor)
 	kfree(mdev->p_uuid);
 	/* mdev->p_uuid = NULL; */
 
-	kfree(mdev->tconn->int_dig_out);
-	kfree(mdev->tconn->int_dig_in);
-	kfree(mdev->tconn->int_dig_vv);
-
 	/* cleanup the rest that has been
 	 * allocated from drbd_new_device
 	 * and actually free the mdev itself */
@@ -3377,6 +3373,9 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
 	write_unlock_irq(&global_state_lock);
 
 	kfree(tconn->name);
+	kfree(tconn->int_dig_out);
+	kfree(tconn->int_dig_in);
+	kfree(tconn->int_dig_vv);
 	kfree(tconn);
 }
 
-- 
1.7.4.1


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

* [PATCH 042/118] drbd: Move cmdname() out of drbd_int.h
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (40 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 041/118] drbd: Do not access tconn after it was freed Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 043/118] drbd: Rename "enum drbd_packets" to "enum drbd_packet" Philipp Reisner
                   ` (77 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

There is no good reason for cmdname() to be an inline function.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4c5d143..e2a33ce 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -221,64 +221,7 @@ enum drbd_packets {
 	P_HAND_SHAKE	      = 0xfffe	/* FIXED for the next century! */
 };
 
-static inline const char *cmdname(enum drbd_packets cmd)
-{
-	/* THINK may need to become several global tables
-	 * when we want to support more than
-	 * one PRO_VERSION */
-	static const char *cmdnames[] = {
-		[P_DATA]	        = "Data",
-		[P_DATA_REPLY]	        = "DataReply",
-		[P_RS_DATA_REPLY]	= "RSDataReply",
-		[P_BARRIER]	        = "Barrier",
-		[P_BITMAP]	        = "ReportBitMap",
-		[P_BECOME_SYNC_TARGET]  = "BecomeSyncTarget",
-		[P_BECOME_SYNC_SOURCE]  = "BecomeSyncSource",
-		[P_UNPLUG_REMOTE]	= "UnplugRemote",
-		[P_DATA_REQUEST]	= "DataRequest",
-		[P_RS_DATA_REQUEST]     = "RSDataRequest",
-		[P_SYNC_PARAM]	        = "SyncParam",
-		[P_SYNC_PARAM89]	= "SyncParam89",
-		[P_PROTOCOL]            = "ReportProtocol",
-		[P_UUIDS]	        = "ReportUUIDs",
-		[P_SIZES]	        = "ReportSizes",
-		[P_STATE]	        = "ReportState",
-		[P_SYNC_UUID]           = "ReportSyncUUID",
-		[P_AUTH_CHALLENGE]      = "AuthChallenge",
-		[P_AUTH_RESPONSE]	= "AuthResponse",
-		[P_PING]		= "Ping",
-		[P_PING_ACK]	        = "PingAck",
-		[P_RECV_ACK]	        = "RecvAck",
-		[P_WRITE_ACK]	        = "WriteAck",
-		[P_RS_WRITE_ACK]	= "RSWriteAck",
-		[P_DISCARD_ACK]	        = "DiscardAck",
-		[P_NEG_ACK]	        = "NegAck",
-		[P_NEG_DREPLY]	        = "NegDReply",
-		[P_NEG_RS_DREPLY]	= "NegRSDReply",
-		[P_BARRIER_ACK]	        = "BarrierAck",
-		[P_STATE_CHG_REQ]       = "StateChgRequest",
-		[P_STATE_CHG_REPLY]     = "StateChgReply",
-		[P_OV_REQUEST]          = "OVRequest",
-		[P_OV_REPLY]            = "OVReply",
-		[P_OV_RESULT]           = "OVResult",
-		[P_CSUM_RS_REQUEST]     = "CsumRSRequest",
-		[P_RS_IS_IN_SYNC]	= "CsumRSIsInSync",
-		[P_COMPRESSED_BITMAP]   = "CBitmap",
-		[P_DELAY_PROBE]         = "DelayProbe",
-		[P_OUT_OF_SYNC]		= "OutOfSync",
-		[P_MAX_CMD]	        = NULL,
-	};
-
-	if (cmd == P_HAND_SHAKE_M)
-		return "HandShakeM";
-	if (cmd == P_HAND_SHAKE_S)
-		return "HandShakeS";
-	if (cmd == P_HAND_SHAKE)
-		return "HandShake";
-	if (cmd >= P_MAX_CMD)
-		return "Unknown";
-	return cmdnames[cmd];
-}
+extern const char *cmdname(enum drbd_packets cmd);
 
 /* for sending/receiving the bitmap,
  * possibly in some encoding scheme */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a9dea6d..097b7a2 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -4101,6 +4101,65 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 	return 1;
 }
 
+const char *cmdname(enum drbd_packets cmd)
+{
+	/* THINK may need to become several global tables
+	 * when we want to support more than
+	 * one PRO_VERSION */
+	static const char *cmdnames[] = {
+		[P_DATA]	        = "Data",
+		[P_DATA_REPLY]	        = "DataReply",
+		[P_RS_DATA_REPLY]	= "RSDataReply",
+		[P_BARRIER]	        = "Barrier",
+		[P_BITMAP]	        = "ReportBitMap",
+		[P_BECOME_SYNC_TARGET]  = "BecomeSyncTarget",
+		[P_BECOME_SYNC_SOURCE]  = "BecomeSyncSource",
+		[P_UNPLUG_REMOTE]	= "UnplugRemote",
+		[P_DATA_REQUEST]	= "DataRequest",
+		[P_RS_DATA_REQUEST]     = "RSDataRequest",
+		[P_SYNC_PARAM]	        = "SyncParam",
+		[P_SYNC_PARAM89]	= "SyncParam89",
+		[P_PROTOCOL]            = "ReportProtocol",
+		[P_UUIDS]	        = "ReportUUIDs",
+		[P_SIZES]	        = "ReportSizes",
+		[P_STATE]	        = "ReportState",
+		[P_SYNC_UUID]           = "ReportSyncUUID",
+		[P_AUTH_CHALLENGE]      = "AuthChallenge",
+		[P_AUTH_RESPONSE]	= "AuthResponse",
+		[P_PING]		= "Ping",
+		[P_PING_ACK]	        = "PingAck",
+		[P_RECV_ACK]	        = "RecvAck",
+		[P_WRITE_ACK]	        = "WriteAck",
+		[P_RS_WRITE_ACK]	= "RSWriteAck",
+		[P_DISCARD_ACK]	        = "DiscardAck",
+		[P_NEG_ACK]	        = "NegAck",
+		[P_NEG_DREPLY]	        = "NegDReply",
+		[P_NEG_RS_DREPLY]	= "NegRSDReply",
+		[P_BARRIER_ACK]	        = "BarrierAck",
+		[P_STATE_CHG_REQ]       = "StateChgRequest",
+		[P_STATE_CHG_REPLY]     = "StateChgReply",
+		[P_OV_REQUEST]          = "OVRequest",
+		[P_OV_REPLY]            = "OVReply",
+		[P_OV_RESULT]           = "OVResult",
+		[P_CSUM_RS_REQUEST]     = "CsumRSRequest",
+		[P_RS_IS_IN_SYNC]	= "CsumRSIsInSync",
+		[P_COMPRESSED_BITMAP]   = "CBitmap",
+		[P_DELAY_PROBE]         = "DelayProbe",
+		[P_OUT_OF_SYNC]		= "OutOfSync",
+		[P_MAX_CMD]	        = NULL,
+	};
+
+	if (cmd == P_HAND_SHAKE_M)
+		return "HandShakeM";
+	if (cmd == P_HAND_SHAKE_S)
+		return "HandShakeS";
+	if (cmd == P_HAND_SHAKE)
+		return "HandShake";
+	if (cmd >= P_MAX_CMD)
+		return "Unknown";
+	return cmdnames[cmd];
+}
+
 #ifdef CONFIG_DRBD_FAULT_INJECTION
 /* Fault insertion support including random number generator shamelessly
  * stolen from kernel/rcutorture.c */
-- 
1.7.4.1


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

* [PATCH 043/118] drbd: Rename "enum drbd_packets" to "enum drbd_packet"
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (41 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 042/118] drbd: Move cmdname() out of drbd_int.h Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 044/118] drbd: Remove redundant initialization Philipp Reisner
                   ` (76 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |   40 +++++++--------
 drivers/block/drbd/drbd_main.c     |   43 +++++++---------
 drivers/block/drbd/drbd_receiver.c |   97 +++++++++++++++++++++--------------
 3 files changed, 97 insertions(+), 83 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e2a33ce..7cc75dd9 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -159,7 +159,7 @@ extern struct drbd_conf **minor_table;
 extern struct ratelimit_state drbd_ratelimit_state;
 
 /* on the wire */
-enum drbd_packets {
+enum drbd_packet {
 	/* receiver (data socket) */
 	P_DATA		      = 0x00,
 	P_DATA_REPLY	      = 0x01, /* Response to P_DATA_REQUEST */
@@ -221,7 +221,7 @@ enum drbd_packets {
 	P_HAND_SHAKE	      = 0xfffe	/* FIXED for the next century! */
 };
 
-extern const char *cmdname(enum drbd_packets cmd);
+extern const char *cmdname(enum drbd_packet cmd);
 
 /* for sending/receiving the bitmap,
  * possibly in some encoding scheme */
@@ -1189,36 +1189,34 @@ extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_f
 extern int _drbd_send_state(struct drbd_conf *mdev);
 extern int drbd_send_state(struct drbd_conf *mdev);
 extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
-			enum drbd_packets cmd, struct p_header *h,
-			size_t size, unsigned msg_flags);
+			  enum drbd_packet cmd, struct p_header *h,
+			  size_t size, unsigned msg_flags);
 #define USE_DATA_SOCKET 1
 #define USE_META_SOCKET 0
 extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
-			enum drbd_packets cmd, struct p_header *h,
-			size_t size);
-extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd,
-			char *data, size_t size);
+			 enum drbd_packet cmd, struct p_header *h, size_t size);
+extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd,
+			  char *data, size_t size);
 extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc);
 extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
 			u32 set_size);
-extern int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
-			struct drbd_epoch_entry *e);
-extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd,
-			struct p_block_req *rp);
-extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
-			struct p_data *dp, int data_size);
-extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd,
+extern int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
+			 struct drbd_epoch_entry *e);
+extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd,
+			    struct p_block_req *rp);
+extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
+			    struct p_data *dp, int data_size);
+extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packet cmd,
 			    sector_t sector, int blksize, u64 block_id);
 extern int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req);
-extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
+extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 			   struct drbd_epoch_entry *e);
 extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req);
 extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
 			      sector_t sector, int size, u64 block_id);
-extern int drbd_send_drequest_csum(struct drbd_conf *mdev,
-				   sector_t sector,int size,
-				   void *digest, int digest_size,
-				   enum drbd_packets cmd);
+extern int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector,
+				   int size, void *digest, int digest_size,
+				   enum drbd_packet cmd);
 extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size);
 
 extern int drbd_send_bitmap(struct drbd_conf *mdev);
@@ -1961,7 +1959,7 @@ static inline void request_ping(struct drbd_conf *mdev)
 }
 
 static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
-	enum drbd_packets cmd)
+				      enum drbd_packet cmd)
 {
 	struct p_header h;
 	return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h));
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 097b7a2..a673693 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1821,7 +1821,7 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 #endif
 
 static void prepare_header80(struct drbd_conf *mdev, struct p_header80 *h,
-			     enum drbd_packets cmd, int size)
+			     enum drbd_packet cmd, int size)
 {
 	h->magic   = cpu_to_be32(DRBD_MAGIC);
 	h->command = cpu_to_be16(cmd);
@@ -1829,7 +1829,7 @@ static void prepare_header80(struct drbd_conf *mdev, struct p_header80 *h,
 }
 
 static void prepare_header95(struct drbd_conf *mdev, struct p_header95 *h,
-			     enum drbd_packets cmd, int size)
+			     enum drbd_packet cmd, int size)
 {
 	h->magic   = cpu_to_be16(DRBD_MAGIC_BIG);
 	h->command = cpu_to_be16(cmd);
@@ -1837,7 +1837,7 @@ static void prepare_header95(struct drbd_conf *mdev, struct p_header95 *h,
 }
 
 static void prepare_header(struct drbd_conf *mdev, struct p_header *h,
-			   enum drbd_packets cmd, int size)
+			   enum drbd_packet cmd, int size)
 {
 	if (mdev->tconn->agreed_pro_version >= 100 || size > DRBD_MAX_SIZE_H80_PACKET)
 		prepare_header95(mdev, &h->h95, cmd, size);
@@ -1847,8 +1847,8 @@ static void prepare_header(struct drbd_conf *mdev, struct p_header *h,
 
 /* the appropriate socket mutex must be held already */
 int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
-			  enum drbd_packets cmd, struct p_header *h,
-			  size_t size, unsigned msg_flags)
+		   enum drbd_packet cmd, struct p_header *h, size_t size,
+		   unsigned msg_flags)
 {
 	int sent, ok;
 
@@ -1872,7 +1872,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
  * when we hold the appropriate socket mutex.
  */
 int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
-		  enum drbd_packets cmd, struct p_header *h, size_t size)
+		  enum drbd_packet cmd, struct p_header *h, size_t size)
 {
 	int ok = 0;
 	struct socket *sock;
@@ -1897,7 +1897,7 @@ int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 	return ok;
 }
 
-int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
+int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd, char *data,
 		   size_t size)
 {
 	struct p_header h;
@@ -1938,7 +1938,8 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 	sock = mdev->tconn->data.socket;
 
 	if (likely(sock != NULL)) {
-		enum drbd_packets cmd = apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
+		enum drbd_packet cmd =
+			apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
 
 		p = &mdev->tconn->data.sbuf.rs_param_95;
 
@@ -2391,10 +2392,8 @@ int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
  * @blksize:	size in byte, needs to be in big endian byte order
  * @block_id:	Id, big endian byte order
  */
-static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
-			  u64 sector,
-			  u32 blksize,
-			  u64 block_id)
+static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
+			  u64 sector, u32 blksize, u64 block_id)
 {
 	int ok;
 	struct p_block_ack p;
@@ -2413,7 +2412,7 @@ static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
 /* dp->sector and dp->block_id already/still in network byte order,
  * data_size is payload size according to dp->head,
  * and may need to be corrected for digest size. */
-int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
+int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
 		     struct p_data *dp, int data_size)
 {
 	data_size -= (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_r_tfm) ?
@@ -2422,7 +2421,7 @@ int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
 			      dp->block_id);
 }
 
-int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd,
+int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd,
 		     struct p_block_req *rp)
 {
 	return _drbd_send_ack(mdev, cmd, rp->sector, rp->blksize, rp->block_id);
@@ -2434,8 +2433,8 @@ int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd,
  * @cmd:	Packet command code.
  * @e:		Epoch entry.
  */
-int drbd_send_ack(struct drbd_conf *mdev,
-	enum drbd_packets cmd, struct drbd_epoch_entry *e)
+int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
+		  struct drbd_epoch_entry *e)
 {
 	return _drbd_send_ack(mdev, cmd,
 			      cpu_to_be64(e->i.sector),
@@ -2445,7 +2444,7 @@ int drbd_send_ack(struct drbd_conf *mdev,
 
 /* This function misuses the block_id field to signal if the blocks
  * are is sync or not. */
-int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd,
+int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packet cmd,
 		     sector_t sector, int blksize, u64 block_id)
 {
 	return _drbd_send_ack(mdev, cmd,
@@ -2468,10 +2467,8 @@ int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
 	return ok;
 }
 
-int drbd_send_drequest_csum(struct drbd_conf *mdev,
-			    sector_t sector, int size,
-			    void *digest, int digest_size,
-			    enum drbd_packets cmd)
+int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector, int size,
+			    void *digest, int digest_size, enum drbd_packet cmd)
 {
 	int ok;
 	struct p_block_req p;
@@ -2742,7 +2739,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
  *  Peer       -> (diskless) R_PRIMARY   (P_DATA_REPLY)
  *  C_SYNC_SOURCE -> C_SYNC_TARGET         (P_RS_DATA_REPLY)
  */
-int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
+int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 		    struct drbd_epoch_entry *e)
 {
 	int ok;
@@ -4101,7 +4098,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 	return 1;
 }
 
-const char *cmdname(enum drbd_packets cmd)
+const char *cmdname(enum drbd_packet cmd)
 {
 	/* THINK may need to become several global tables
 	 * when we want to support more than
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 24c906f..72b2512 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -697,15 +697,16 @@ out:
 	return s_estab;
 }
 
-static int drbd_send_fp(struct drbd_conf *mdev,
-	struct socket *sock, enum drbd_packets cmd)
+static int drbd_send_fp(struct drbd_conf *mdev, struct socket *sock,
+			enum drbd_packet cmd)
 {
 	struct p_header *h = &mdev->tconn->data.sbuf.header;
 
 	return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0);
 }
 
-static enum drbd_packets drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock)
+static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev,
+				     struct socket *sock)
 {
 	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
 	int rr;
@@ -926,8 +927,8 @@ out_release_sockets:
 	return -1;
 }
 
-static bool decode_header(struct drbd_conf *mdev, struct p_header *h, enum drbd_packets *cmd,
-			  unsigned int *packet_size)
+static bool decode_header(struct drbd_conf *mdev, struct p_header *h,
+			  enum drbd_packet *cmd, unsigned int *packet_size)
 {
 	u32 vol_n_len;
 
@@ -949,7 +950,8 @@ static bool decode_header(struct drbd_conf *mdev, struct p_header *h, enum drbd_
 	return true;
 }
 
-static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsigned int *packet_size)
+static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
+			    unsigned int *packet_size)
 {
 	struct p_header *h = &mdev->tconn->data.rbuf.header;
 	int r;
@@ -1174,7 +1176,8 @@ fail:
 	return err;
 }
 
-static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
+			   unsigned int data_size)
 {
 	int rv;
 	struct p_barrier *p = &mdev->tconn->data.rbuf.barrier;
@@ -1503,7 +1506,8 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
 	return NULL;
 }
 
-static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
+			     unsigned int data_size)
 {
 	struct drbd_request *req;
 	sector_t sector;
@@ -1532,7 +1536,8 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	return ok;
 }
 
-static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
+			       unsigned int data_size)
 {
 	sector_t sector;
 	int ok;
@@ -1685,7 +1690,8 @@ static unsigned long wire_flags_to_bio(struct drbd_conf *mdev, u32 dpf)
 }
 
 /* mirrored write */
-static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
+			unsigned int data_size)
 {
 	sector_t sector;
 	struct drbd_epoch_entry *e;
@@ -1970,7 +1976,8 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
 }
 
 
-static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int digest_size)
+static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
+			       unsigned int digest_size)
 {
 	sector_t sector;
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
@@ -2695,7 +2702,8 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
 	return 1;
 }
 
-static int receive_protocol(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_protocol(struct drbd_conf *mdev, enum drbd_packet cmd,
+			    unsigned int data_size)
 {
 	struct p_protocol *p = &mdev->tconn->data.rbuf.protocol;
 	int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
@@ -2794,7 +2802,8 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
 	return tfm;
 }
 
-static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int packet_size)
+static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
+			     unsigned int packet_size)
 {
 	int ok = true;
 	struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95;
@@ -2958,7 +2967,8 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
 		     (unsigned long long)a, (unsigned long long)b);
 }
 
-static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
+			 unsigned int data_size)
 {
 	struct p_sizes *p = &mdev->tconn->data.rbuf.sizes;
 	enum determine_dev_size dd = unchanged;
@@ -3061,7 +3071,8 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	return true;
 }
 
-static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
+			 unsigned int data_size)
 {
 	struct p_uuids *p = &mdev->tconn->data.rbuf.uuids;
 	u64 *p_uuid;
@@ -3155,7 +3166,8 @@ static union drbd_state convert_state(union drbd_state ps)
 	return ms;
 }
 
-static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
+			     unsigned int data_size)
 {
 	struct p_req_state *p = &mdev->tconn->data.rbuf.req_state;
 	union drbd_state mask, val;
@@ -3181,7 +3193,8 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
 	return true;
 }
 
-static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
+			 unsigned int data_size)
 {
 	struct p_state *p = &mdev->tconn->data.rbuf.state;
 	union drbd_state os, ns, peer_state;
@@ -3333,7 +3346,8 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	return true;
 }
 
-static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
+			     unsigned int data_size)
 {
 	struct p_rs_uuid *p = &mdev->tconn->data.rbuf.rs_uuid;
 
@@ -3529,7 +3543,8 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
    in order to be agnostic to the 32 vs 64 bits issue.
 
    returns 0 on failure, 1 if we successfully received it. */
-static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
+			  unsigned int data_size)
 {
 	struct bm_xfer_ctx c;
 	void *buffer;
@@ -3620,7 +3635,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
 	return ok;
 }
 
-static int receive_skip(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd,
+			unsigned int data_size)
 {
 	/* TODO zero copy sink :) */
 	static char sink[128];
@@ -3640,7 +3656,8 @@ static int receive_skip(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
 	return size == 0;
 }
 
-static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
+				unsigned int data_size)
 {
 	/* Make sure we've acked all the TCP data associated
 	 * with the data requests being unplugged */
@@ -3649,7 +3666,8 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, u
 	return true;
 }
 
-static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
+static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
+			       unsigned int data_size)
 {
 	struct p_block_desc *p = &mdev->tconn->data.rbuf.block_desc;
 
@@ -3668,7 +3686,8 @@ static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packets cmd, un
 	return true;
 }
 
-typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, enum drbd_packets cmd, unsigned int to_receive);
+typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, enum drbd_packet cmd,
+				  unsigned int to_receive);
 
 struct data_cmd {
 	int expect_payload;
@@ -3715,7 +3734,7 @@ static void drbdd(struct drbd_conf *mdev)
 {
 	struct p_header *header = &mdev->tconn->data.rbuf.header;
 	unsigned int packet_size;
-	enum drbd_packets cmd;
+	enum drbd_packet cmd;
 	size_t shs; /* sub header size */
 	int rv;
 
@@ -3942,7 +3961,7 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
 	const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
 	unsigned int length;
-	enum drbd_packets cmd;
+	enum drbd_packet cmd;
 	int rv;
 
 	rv = drbd_send_handshake(mdev);
@@ -4023,7 +4042,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
 	unsigned int resp_size;
 	struct hash_desc desc;
-	enum drbd_packets cmd;
+	enum drbd_packet cmd;
 	unsigned int length;
 	int rv;
 
@@ -4195,7 +4214,7 @@ int drbdd_init(struct drbd_thread *thi)
 
 /* ********* acknowledge sender ******** */
 
-static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_req_state_reply *p = &mdev->tconn->meta.rbuf.req_state_reply;
 
@@ -4213,13 +4232,13 @@ static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_Ping(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_Ping(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	return drbd_send_ping_ack(mdev);
 
 }
 
-static int got_PingAck(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_PingAck(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	/* restore idle timeout */
 	mdev->tconn->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
@@ -4229,7 +4248,7 @@ static int got_PingAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_IsInSync(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_IsInSync(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
@@ -4274,7 +4293,7 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector,
 	return true;
 }
 
-static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
@@ -4315,7 +4334,7 @@ static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 					     what, false);
 }
 
-static int got_NegAck(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_NegAck(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
@@ -4348,7 +4367,7 @@ static int got_NegAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	sector_t sector = be64_to_cpu(p->sector);
@@ -4362,7 +4381,7 @@ static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 					     NEG_ACKED, false);
 }
 
-static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	sector_t sector;
 	int size;
@@ -4393,7 +4412,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_barrier_ack *p = &mdev->tconn->meta.rbuf.barrier_ack;
 
@@ -4409,7 +4428,7 @@ static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_OVResult(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_OVResult(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack;
 	struct drbd_work *w;
@@ -4453,14 +4472,14 @@ static int got_OVResult(struct drbd_conf *mdev, enum drbd_packets cmd)
 	return true;
 }
 
-static int got_skip(struct drbd_conf *mdev, enum drbd_packets cmd)
+static int got_skip(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	return true;
 }
 
 struct asender_cmd {
 	size_t pkt_size;
-	int (*process)(struct drbd_conf *mdev, enum drbd_packets cmd);
+	int (*process)(struct drbd_conf *mdev, enum drbd_packet cmd);
 };
 
 static struct asender_cmd *get_asender_cmd(int cmd)
@@ -4503,7 +4522,7 @@ int drbd_asender(struct drbd_thread *thi)
 	int expect   = sizeof(struct p_header);
 	int ping_timeout_active = 0;
 	int empty, pkt_size;
-	enum drbd_packets cmd_nr;
+	enum drbd_packet cmd_nr;
 
 	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
 
-- 
1.7.4.1


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

* [PATCH 044/118] drbd: Remove redundant initialization
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (42 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 043/118] drbd: Rename "enum drbd_packets" to "enum drbd_packet" Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 045/118] drbd: Initialize the sequence number sent over the network even when not used Philipp Reisner
                   ` (75 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

packet_seq is initialized by both sides of a connection in
drbd_connect().

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a673693..32e44e3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2953,7 +2953,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	atomic_set(&mdev->rs_pending_cnt, 0);
 	atomic_set(&mdev->unacked_cnt, 0);
 	atomic_set(&mdev->local_cnt, 0);
-	atomic_set(&mdev->packet_seq, 0);
 	atomic_set(&mdev->pp_in_use, 0);
 	atomic_set(&mdev->pp_in_use_by_net, 0);
 	atomic_set(&mdev->rs_sect_in, 0);
-- 
1.7.4.1


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

* [PATCH 045/118] drbd: Initialize the sequence number sent over the network even when not used
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (43 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 044/118] drbd: Remove redundant initialization Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 046/118] drbd: Move sequence number logic into drbd_receiver.c and simplify it Philipp Reisner
                   ` (74 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 32e44e3..fbd3f04 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2753,7 +2753,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	prepare_header(mdev, &p.head, cmd, sizeof(p) - sizeof(struct p_header80) + dgs + e->i.size);
 	p.sector   = cpu_to_be64(e->i.sector);
 	p.block_id = e->block_id;
-	/* p.seq_num  = 0;    No sequence numbers here.. */
+	p.seq_num = 0;  /* unused */
 
 	/* Only called by our kernel thread.
 	 * This one may be interrupted by DRBD_SIG and/or DRBD_SIGKILL
-- 
1.7.4.1


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

* [PATCH 046/118] drbd: Move sequence number logic into drbd_receiver.c and simplify it
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (44 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 045/118] drbd: Initialize the sequence number sent over the network even when not used Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 047/118] drbd: Move some functions to where they are used Philipp Reisner
                   ` (73 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

These things are only used there.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 7cc75dd9..fafadb6 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2355,33 +2355,6 @@ static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val)
 	return changed;
 }
 
-static inline int seq_cmp(u32 a, u32 b)
-{
-	/* we assume wrap around at 32bit.
-	 * for wrap around at 24bit (old atomic_t),
-	 * we'd have to
-	 *  a <<= 8; b <<= 8;
-	 */
-	return (s32)(a) - (s32)(b);
-}
-#define seq_lt(a, b) (seq_cmp((a), (b)) < 0)
-#define seq_gt(a, b) (seq_cmp((a), (b)) > 0)
-#define seq_ge(a, b) (seq_cmp((a), (b)) >= 0)
-#define seq_le(a, b) (seq_cmp((a), (b)) <= 0)
-/* CAUTION: please no side effects in arguments! */
-#define seq_max(a, b) ((u32)(seq_gt((a), (b)) ? (a) : (b)))
-
-static inline void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq)
-{
-	unsigned int m;
-	spin_lock(&mdev->peer_seq_lock);
-	m = seq_max(mdev->peer_seq, new_seq);
-	mdev->peer_seq = m;
-	spin_unlock(&mdev->peer_seq_lock);
-	if (m == new_seq)
-		wake_up(&mdev->seq_wait);
-}
-
 static inline void drbd_update_congested(struct drbd_conf *mdev)
 {
 	struct sock *sk = mdev->tconn->data.socket->sk;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 72b2512..0d9d777 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1625,6 +1625,33 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 	return ok;
 }
 
+static bool seq_greater(u32 a, u32 b)
+{
+	/*
+	 * We assume 32-bit wrap-around here.
+	 * For 24-bit wrap-around, we would have to shift:
+	 *  a <<= 8; b <<= 8;
+	 */
+	return (s32)a - (s32)b > 0;
+}
+
+static u32 seq_max(u32 a, u32 b)
+{
+	return seq_greater(a, b) ? a : b;
+}
+
+static void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq)
+{
+	unsigned int m;
+
+	spin_lock(&mdev->peer_seq_lock);
+	m = seq_max(mdev->peer_seq, new_seq);
+	mdev->peer_seq = m;
+	spin_unlock(&mdev->peer_seq_lock);
+	if (m == new_seq)
+		wake_up(&mdev->seq_wait);
+}
+
 /* Called from receive_Data.
  * Synchronize packets on sock with packets on msock.
  *
@@ -1655,7 +1682,7 @@ static int drbd_wait_peer_seq(struct drbd_conf *mdev, const u32 packet_seq)
 	spin_lock(&mdev->peer_seq_lock);
 	for (;;) {
 		prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE);
-		if (seq_le(packet_seq, mdev->peer_seq+1))
+		if (!seq_greater(packet_seq, mdev->peer_seq + 1))
 			break;
 		if (signal_pending(current)) {
 			ret = -ERESTARTSYS;
-- 
1.7.4.1


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

* [PATCH 047/118] drbd: Move some functions to where they are used
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (45 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 046/118] drbd: Move sequence number logic into drbd_receiver.c and simplify it Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 048/118] drbd: struct drbd_request: Introduce a new collision flag Philipp Reisner
                   ` (72 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Move drbd_update_congested() to drbd_main.c, and drbd_req_new() and
drbd_req_free() to drbd_req.c: those functions are not used anywhere
else.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h  |    7 -------
 drivers/block/drbd/drbd_main.c |    7 +++++++
 drivers/block/drbd/drbd_req.c  |   29 +++++++++++++++++++++++++++++
 drivers/block/drbd/drbd_req.h  |   26 --------------------------
 4 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index fafadb6..e917859 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2355,13 +2355,6 @@ static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val)
 	return changed;
 }
 
-static inline void drbd_update_congested(struct drbd_conf *mdev)
-{
-	struct sock *sk = mdev->tconn->data.socket->sk;
-	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
-		set_bit(NET_CONGESTED, &mdev->flags);
-}
-
 static inline int drbd_queue_order_type(struct drbd_conf *mdev)
 {
 	/* sorry, we currently have no working implementation
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index fbd3f04..13aadca 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2528,6 +2528,13 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 	return drop_it; /* && (mdev->state == R_PRIMARY) */;
 }
 
+static void drbd_update_congested(struct drbd_conf *mdev)
+{
+	struct sock *sk = mdev->tconn->data.socket->sk;
+	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
+		set_bit(NET_CONGESTED, &mdev->flags);
+}
+
 /* The idea of sendpage seems to be to put some kind of reference
  * to the page into the skb, and to hand it over to the NIC. In
  * this process get_page() gets called.
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 74179f7..25fa87c 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -56,6 +56,35 @@ static void _drbd_end_io_acct(struct drbd_conf *mdev, struct drbd_request *req)
 	part_stat_unlock();
 }
 
+static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
+					       struct bio *bio_src)
+{
+	struct drbd_request *req;
+
+	req = mempool_alloc(drbd_request_mempool, GFP_NOIO);
+	if (!req)
+		return NULL;
+
+	drbd_req_make_private_bio(req, bio_src);
+	req->rq_state    = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
+	req->mdev        = mdev;
+	req->master_bio  = bio_src;
+	req->epoch       = 0;
+	drbd_clear_interval(&req->i);
+	req->i.sector     = bio_src->bi_sector;
+	req->i.size      = bio_src->bi_size;
+	INIT_LIST_HEAD(&req->tl_requests);
+	INIT_LIST_HEAD(&req->w.list);
+
+	return req;
+}
+
+static void drbd_req_free(struct drbd_request *req)
+{
+	mempool_free(req, drbd_request_mempool);
+}
+
+/* rw is bio_data_dir(), only READ or WRITE */
 static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const int rw)
 {
 	const unsigned long s = req->rq_state;
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 4b0858b..431e3f9 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -234,32 +234,6 @@ static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bi
 	bio->bi_next     = NULL;
 }
 
-static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
-	struct bio *bio_src)
-{
-	struct drbd_request *req =
-		mempool_alloc(drbd_request_mempool, GFP_NOIO);
-	if (likely(req)) {
-		drbd_req_make_private_bio(req, bio_src);
-
-		req->rq_state    = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
-		req->mdev        = mdev;
-		req->master_bio  = bio_src;
-		req->epoch       = 0;
-		req->i.sector     = bio_src->bi_sector;
-		req->i.size      = bio_src->bi_size;
-		drbd_clear_interval(&req->i);
-		INIT_LIST_HEAD(&req->tl_requests);
-		INIT_LIST_HEAD(&req->w.list);
-	}
-	return req;
-}
-
-static inline void drbd_req_free(struct drbd_request *req)
-{
-	mempool_free(req, drbd_request_mempool);
-}
-
 /* Short lived temporary struct on the stack.
  * We could squirrel the error to be returned into
  * bio->bi_size, or similar. But that would be too ugly. */
-- 
1.7.4.1


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

* [PATCH 048/118] drbd: struct drbd_request: Introduce a new collision flag
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (46 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 047/118] drbd: Move some functions to where they are used Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 049/118] drbd: Remove redundant check from drbd_contains_interval() Philipp Reisner
                   ` (71 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

This flag is set when a processes puts itself to sleep to wait for a
conflicting request to complete.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0d9d777..ed24dc3 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1819,6 +1819,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 		first = 1;
 		for (;;) {
 			struct drbd_interval *i;
+			struct drbd_request *req2;
 			int have_unacked = 0;
 			int have_conflict = 0;
 			prepare_to_wait(&mdev->misc_wait, &wait,
@@ -1826,8 +1827,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 			i = drbd_find_overlap(&mdev->write_requests, sector, size);
 			if (i) {
-				struct drbd_request *req2 =
-					container_of(i, struct drbd_request, i);
+				req2 = container_of(i, struct drbd_request, i);
 
 				/* only ALERT on first iteration,
 				 * we may be woken up early... */
@@ -1873,6 +1873,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 				goto out_interrupted;
 			}
 
+			/* Indicate to wake up mdev->misc_wait upon completion.  */
+			req2->rq_state |= RQ_COLLISION;
+
 			spin_unlock_irq(&mdev->tconn->req_lock);
 			if (first) {
 				first = 0;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 25fa87c..8b4ba94 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -176,45 +176,9 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	    req->epoch == mdev->tconn->newest_tle->br_number)
 		queue_barrier(mdev);
 
-	/* we need to do the conflict detection stuff,
-	 * if the epoch_entries tree is non-empty and
-	 * this request has completed on the network */
-	if ((s & RQ_NET_DONE) && !RB_EMPTY_ROOT(&mdev->epoch_entries)) {
-		const sector_t sector = req->i.sector;
-		const int size = req->i.size;
-		struct drbd_interval *i;
-
-		/* ASSERT:
-		 * there must be no conflicting requests, since
-		 * they must have been failed on the spot */
-
-		i = drbd_find_overlap(&mdev->write_requests, sector, size);
-		if (i) {
-			struct drbd_request *req2 =
-				container_of(i, struct drbd_request, i);
-
-			dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
-			      "other: %p %llus +%u\n",
-			      req, (unsigned long long)sector, size,
-			      i, (unsigned long long)req2->i.sector, req2->i.size);
-		}
-
-		/* maybe "wake" those conflicting epoch entries
-		 * that wait for this request to finish.
-		 *
-		 * currently, there can be only _one_ such ee
-		 * (well, or some more, which would be pending
-		 * P_DISCARD_ACK not yet sent by the asender...),
-		 * since we block the receiver thread upon the
-		 * first conflict detection, which will wait on
-		 * misc_wait.  maybe we want to assert that?
-		 *
-		 * anyways, if we found one,
-		 * we just have to do a wake_up.  */
-		i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
-		if (i)
-			wake_up(&mdev->misc_wait);
-	}
+	/* Wake up any processes waiting for this request to complete.  */
+	if ((s & RQ_NET_DONE) && (s & RQ_COLLISION))
+		wake_up(&mdev->misc_wait);
 }
 
 void complete_master_bio(struct drbd_conf *mdev,
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 431e3f9..7a7464a 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -194,6 +194,12 @@ enum drbd_req_state_bits {
 
 	/* Should call drbd_al_complete_io() for this request... */
 	__RQ_IN_ACT_LOG,
+
+	/*
+	 * Set when a processes puts itself to sleep to wait for this request
+	 * to complete.
+	 */
+	__RQ_COLLISION,
 };
 
 #define RQ_LOCAL_PENDING   (1UL << __RQ_LOCAL_PENDING)
@@ -214,6 +220,7 @@ enum drbd_req_state_bits {
 
 #define RQ_WRITE           (1UL << __RQ_WRITE)
 #define RQ_IN_ACT_LOG      (1UL << __RQ_IN_ACT_LOG)
+#define RQ_COLLISION	   (1UL << __RQ_COLLISION)
 
 /* For waking up the frozen transfer log mod_req() has to return if the request
    should be counted in the epoch object*/
-- 
1.7.4.1


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

* [PATCH 049/118] drbd: Remove redundant check from drbd_contains_interval()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (47 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 048/118] drbd: struct drbd_request: Introduce a new collision flag Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 050/118] drbd: Allow to wait for the completion of an epoch entry as well Philipp Reisner
                   ` (70 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_interval.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_interval.c b/drivers/block/drbd/drbd_interval.c
index b77a9bd..0d17eaa 100644
--- a/drivers/block/drbd/drbd_interval.c
+++ b/drivers/block/drbd/drbd_interval.c
@@ -99,7 +99,7 @@ drbd_contains_interval(struct rb_root *root, sector_t sector,
 		else if (interval > here)
 			node = node->rb_right;
 		else
-			return interval->sector == sector;
+			return true;
 	}
 	return false;
 }
-- 
1.7.4.1


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

* [PATCH 050/118] drbd: Allow to wait for the completion of an epoch entry as well
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (48 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 049/118] drbd: Remove redundant check from drbd_contains_interval() Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 051/118] drbd: _req_conflicts(): Get rid of the epoch_entries tree Philipp Reisner
                   ` (69 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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_interval.h |    1 +
 drivers/block/drbd/drbd_receiver.c |   35 ++++++++++++++++++++++-------------
 drivers/block/drbd/drbd_req.c      |   23 ++++++++++++++++++-----
 drivers/block/drbd/drbd_req.h      |    7 -------
 4 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h
index a847b4a..9d1e5eb 100644
--- a/drivers/block/drbd/drbd_interval.h
+++ b/drivers/block/drbd/drbd_interval.h
@@ -9,6 +9,7 @@ struct drbd_interval {
 	sector_t sector;	/* start sector of the interval */
 	unsigned int size;	/* size in bytes */
 	sector_t end;		/* highest interval end in subtree */
+	int waiting:1;
 };
 
 static inline void drbd_clear_interval(struct drbd_interval *i)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index ed24dc3..558c630 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -334,13 +334,15 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 		goto fail;
 
 	drbd_clear_interval(&e->i);
+	e->i.size = data_size;
+	e->i.sector = sector;
+	e->i.waiting = false;
+
 	e->epoch = NULL;
 	e->mdev = mdev;
 	e->pages = page;
 	atomic_set(&e->pending_bios, 0);
-	e->i.size = data_size;
 	e->flags = 0;
-	e->i.sector = sector;
 	/*
 	 * The block_id is opaque to the receiver.  It is not endianness
 	 * converted, and sent back to the sender unchanged.
@@ -1176,6 +1178,19 @@ fail:
 	return err;
 }
 
+static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
+					     struct drbd_epoch_entry *e)
+{
+	struct drbd_interval *i = &e->i;
+
+	drbd_remove_interval(&mdev->write_requests, i);
+	drbd_clear_interval(i);
+
+	/* Wake up any processes waiting for this epoch entry to complete.  */
+	if (i->waiting)
+		wake_up(&mdev->misc_wait);
+}
+
 static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
 			   unsigned int data_size)
 {
@@ -1595,8 +1610,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	if (mdev->tconn->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->tconn->req_lock);
 		D_ASSERT(!drbd_interval_empty(&e->i));
-		drbd_remove_interval(&mdev->epoch_entries, &e->i);
-		drbd_clear_interval(&e->i);
+		drbd_remove_epoch_entry_interval(mdev, e);
 		spin_unlock_irq(&mdev->tconn->req_lock);
 	} else
 		D_ASSERT(drbd_interval_empty(&e->i));
@@ -1616,8 +1630,7 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
 
 	spin_lock_irq(&mdev->tconn->req_lock);
 	D_ASSERT(!drbd_interval_empty(&e->i));
-	drbd_remove_interval(&mdev->epoch_entries, &e->i);
-	drbd_clear_interval(&e->i);
+	drbd_remove_epoch_entry_interval(mdev, e);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	dec_unacked(mdev);
@@ -1864,17 +1877,14 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 			}
 
 			if (signal_pending(current)) {
-				drbd_remove_interval(&mdev->epoch_entries, &e->i);
-				drbd_clear_interval(&e->i);
-
+				drbd_remove_epoch_entry_interval(mdev, e);
 				spin_unlock_irq(&mdev->tconn->req_lock);
-
 				finish_wait(&mdev->misc_wait, &wait);
 				goto out_interrupted;
 			}
 
 			/* Indicate to wake up mdev->misc_wait upon completion.  */
-			req2->rq_state |= RQ_COLLISION;
+			i->waiting = true;
 
 			spin_unlock_irq(&mdev->tconn->req_lock);
 			if (first) {
@@ -1926,8 +1936,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->tconn->req_lock);
 	list_del(&e->w.list);
-	drbd_remove_interval(&mdev->epoch_entries, &e->i);
-	drbd_clear_interval(&e->i);
+	drbd_remove_epoch_entry_interval(mdev, e);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 	if (e->flags & EE_CALL_AL_COMPLETE_IO)
 		drbd_al_complete_io(mdev, e->i.sector);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8b4ba94..078f77b 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -70,9 +70,12 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 	req->mdev        = mdev;
 	req->master_bio  = bio_src;
 	req->epoch       = 0;
+
 	drbd_clear_interval(&req->i);
 	req->i.sector     = bio_src->bi_sector;
 	req->i.size      = bio_src->bi_size;
+	req->i.waiting = false;
+
 	INIT_LIST_HEAD(&req->tl_requests);
 	INIT_LIST_HEAD(&req->w.list);
 
@@ -175,10 +178,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
 	    (s & RQ_NET_SENT) != 0 &&
 	    req->epoch == mdev->tconn->newest_tle->br_number)
 		queue_barrier(mdev);
-
-	/* Wake up any processes waiting for this request to complete.  */
-	if ((s & RQ_NET_DONE) && (s & RQ_COLLISION))
-		wake_up(&mdev->misc_wait);
 }
 
 void complete_master_bio(struct drbd_conf *mdev,
@@ -188,6 +187,20 @@ void complete_master_bio(struct drbd_conf *mdev,
 	dec_ap_bio(mdev);
 }
 
+
+static void drbd_remove_request_interval(struct rb_root *root,
+					 struct drbd_request *req)
+{
+	struct drbd_conf *mdev = req->mdev;
+	struct drbd_interval *i = &req->i;
+
+	drbd_remove_interval(root, i);
+
+	/* Wake up any processes waiting for this request to complete.  */
+	if (i->waiting)
+		wake_up(&mdev->misc_wait);
+}
+
 /* Helper for __req_mod().
  * Set m->bio to the master bio, if it is fit to be completed,
  * or leave it alone (it is initialized to NULL in __req_mod),
@@ -251,7 +264,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 				root = &mdev->write_requests;
 			else
 				root = &mdev->read_requests;
-			drbd_remove_interval(root, &req->i);
+			drbd_remove_request_interval(root, req);
 		} else
 			D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 7a7464a..431e3f9 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -194,12 +194,6 @@ enum drbd_req_state_bits {
 
 	/* Should call drbd_al_complete_io() for this request... */
 	__RQ_IN_ACT_LOG,
-
-	/*
-	 * Set when a processes puts itself to sleep to wait for this request
-	 * to complete.
-	 */
-	__RQ_COLLISION,
 };
 
 #define RQ_LOCAL_PENDING   (1UL << __RQ_LOCAL_PENDING)
@@ -220,7 +214,6 @@ enum drbd_req_state_bits {
 
 #define RQ_WRITE           (1UL << __RQ_WRITE)
 #define RQ_IN_ACT_LOG      (1UL << __RQ_IN_ACT_LOG)
-#define RQ_COLLISION	   (1UL << __RQ_COLLISION)
 
 /* For waking up the frozen transfer log mod_req() has to return if the request
    should be counted in the epoch object*/
-- 
1.7.4.1


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

* [PATCH 051/118] drbd: _req_conflicts(): Get rid of the epoch_entries tree
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (49 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 050/118] drbd: Allow to wait for the completion of an epoch entry as well Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 052/118] drbd: Remove unnecessary reference counting left-over Philipp Reisner
                   ` (68 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Instead of keeping a separate tree for local and remote write requests
for finding requests and for conflict detection, use the same tree for
both purposes.  Introduce a flag to allow distinguishing the two
possible types of entries in this tree.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e917859..faa7cbd 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1045,9 +1045,6 @@ struct drbd_conf {
 	struct list_head read_ee;   /* IO in progress (any read) */
 	struct list_head net_ee;    /* zero-copy network send in progress */
 
-	/* Interval tree of pending remote write requests (struct drbd_epoch_entry) */
-	struct rb_root epoch_entries;
-
 	/* this one is protected by ee_lock, single thread */
 	struct drbd_epoch_entry *last_write_w_barrier;
 
diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h
index 9d1e5eb..4010ad9 100644
--- a/drivers/block/drbd/drbd_interval.h
+++ b/drivers/block/drbd/drbd_interval.h
@@ -9,6 +9,7 @@ struct drbd_interval {
 	sector_t sector;	/* start sector of the interval */
 	unsigned int size;	/* size in bytes */
 	sector_t end;		/* highest interval end in subtree */
+	int local:1		/* local or remote request? */;
 	int waiting:1;
 };
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 13aadca..a2417e4 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3450,7 +3450,6 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 		goto out_no_tl;
 	mdev->read_requests = RB_ROOT;
 	mdev->write_requests = RB_ROOT;
-	mdev->epoch_entries = RB_ROOT;
 
 	mdev->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
 	if (!mdev->current_epoch)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 558c630..cde48f3 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -336,6 +336,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 	drbd_clear_interval(&e->i);
 	e->i.size = data_size;
 	e->i.sector = sector;
+	e->i.local = false;
 	e->i.waiting = false;
 
 	e->epoch = NULL;
@@ -1512,7 +1513,7 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
 
 	/* Request object according to our peer */
 	req = (struct drbd_request *)(unsigned long)id;
-	if (drbd_contains_interval(root, sector, &req->i))
+	if (drbd_contains_interval(root, sector, &req->i) && req->i.local)
 		return req;
 	if (!missing_ok) {
 		dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func,
@@ -1792,17 +1793,12 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 		/* conflict detection and handling:
 		 * 1. wait on the sequence number,
 		 *    in case this data packet overtook ACK packets.
-		 * 2. check our interval trees for conflicting requests:
-		 *    we only need to check the write_requests tree; the
-		 *    epoch_entries tree cannot contain any overlaps because
-		 *    they were already eliminated on the submitting node.
+		 * 2. check for conflicting write requests.
 		 *
 		 * Note: for two_primaries, we are protocol C,
 		 * so there cannot be any request that is DONE
 		 * but still on the transfer log.
 		 *
-		 * unconditionally add to the epoch_entries tree.
-		 *
 		 * if no conflicting request is found:
 		 *    submit.
 		 *
@@ -1827,12 +1823,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 		spin_lock_irq(&mdev->tconn->req_lock);
 
-		drbd_insert_interval(&mdev->epoch_entries, &e->i);
-
 		first = 1;
 		for (;;) {
 			struct drbd_interval *i;
-			struct drbd_request *req2;
 			int have_unacked = 0;
 			int have_conflict = 0;
 			prepare_to_wait(&mdev->misc_wait, &wait,
@@ -1840,18 +1833,23 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 			i = drbd_find_overlap(&mdev->write_requests, sector, size);
 			if (i) {
-				req2 = container_of(i, struct drbd_request, i);
-
 				/* only ALERT on first iteration,
 				 * we may be woken up early... */
 				if (first)
-					dev_alert(DEV, "%s[%u] Concurrent local write detected!"
+					dev_alert(DEV, "%s[%u] Concurrent %s write detected!"
 					      "	new: %llus +%u; pending: %llus +%u\n",
 					      current->comm, current->pid,
+					      i->local ? "local" : "remote",
 					      (unsigned long long)sector, size,
-					      (unsigned long long)req2->i.sector, req2->i.size);
-				if (req2->rq_state & RQ_NET_PENDING)
-					++have_unacked;
+					      (unsigned long long)i->sector, i->size);
+
+				if (i->local) {
+					struct drbd_request *req2;
+
+					req2 = container_of(i, struct drbd_request, i);
+					if (req2->rq_state & RQ_NET_PENDING)
+						++have_unacked;
+				}
 				++have_conflict;
 			}
 			if (!have_conflict)
@@ -1877,7 +1875,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 			}
 
 			if (signal_pending(current)) {
-				drbd_remove_epoch_entry_interval(mdev, e);
 				spin_unlock_irq(&mdev->tconn->req_lock);
 				finish_wait(&mdev->misc_wait, &wait);
 				goto out_interrupted;
@@ -1900,6 +1897,8 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 			spin_lock_irq(&mdev->tconn->req_lock);
 		}
 		finish_wait(&mdev->misc_wait, &wait);
+
+		drbd_insert_interval(&mdev->write_requests, &e->i);
 	}
 
 	list_add(&e->w.list, &mdev->active_ee);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 078f77b..df5f106 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -74,6 +74,7 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 	drbd_clear_interval(&req->i);
 	req->i.sector     = bio_src->bi_sector;
 	req->i.size      = bio_src->bi_size;
+	req->i.local = true;
 	req->i.waiting = false;
 
 	INIT_LIST_HEAD(&req->tl_requests);
@@ -317,8 +318,6 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
  * to happen, but this is the rationale why we also have to check for
  * conflicting requests with local origin, and why we have to do so regardless
  * of whether we allowed multiple primaries.
- *
- * In case we only have one primary, the epoch_entries tree is empty.
  */
 static int _req_conflicts(struct drbd_request *req)
 {
@@ -334,35 +333,16 @@ static int _req_conflicts(struct drbd_request *req)
 
 	i = drbd_find_overlap(&mdev->write_requests, sector, size);
 	if (i) {
-		struct drbd_request *req2 =
-			container_of(i, struct drbd_request, i);
-
-		dev_alert(DEV, "%s[%u] Concurrent local write detected! "
+		dev_alert(DEV, "%s[%u] Concurrent %s write detected! "
 		      "[DISCARD L] new: %llus +%u; "
 		      "pending: %llus +%u\n",
 		      current->comm, current->pid,
+		      i->local ? "local" : "remote",
 		      (unsigned long long)sector, size,
-		      (unsigned long long)req2->i.sector, req2->i.size);
+		      (unsigned long long)i->sector, i->size);
 		goto out_conflict;
 	}
 
-	if (!RB_EMPTY_ROOT(&mdev->epoch_entries)) {
-		/* check for overlapping requests with remote origin */
-		i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
-		if (i) {
-			struct drbd_epoch_entry *e =
-				container_of(i, struct drbd_epoch_entry, i);
-
-			dev_alert(DEV, "%s[%u] Concurrent remote write detected!"
-			      " [DISCARD L] new: %llus +%u; "
-			      "pending: %llus +%u\n",
-			      current->comm, current->pid,
-			      (unsigned long long)sector, size,
-			      (unsigned long long)e->i.sector, e->i.size);
-			goto out_conflict;
-		}
-	}
-
 	/* this is like it should be, and what we expected.
 	 * our users do behave after all... */
 	put_net_conf(mdev->tconn);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index afad8ea..0359600 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -123,7 +123,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
 	list_add_tail(&e->w.list, &mdev->done_ee);
 
 	/*
-	 * Do not remove from the epoch_entries tree here: we did not send the
+	 * Do not remove from the write_requests tree here: we did not send the
 	 * Ack yet and did not wake possibly waiting conflicting requests.
 	 * Removed from the tree from "drbd_process_done_ee" within the
 	 * appropriate w.cb (e_end_block/e_end_resync_block) or from
-- 
1.7.4.1


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

* [PATCH 052/118] drbd: Remove unnecessary reference counting left-over
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (50 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 051/118] drbd: _req_conflicts(): Get rid of the epoch_entries tree Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 053/118] drbd: Defer new writes when detecting conflicting writes Philipp Reisner
                   ` (67 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Nothing in this function accesses mdev->tconn->net_conf, so there is no
need for get_net_conf() / put_net_conf() anymore.

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

diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index df5f106..e11ea47 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -328,9 +328,6 @@ static int _req_conflicts(struct drbd_request *req)
 
 	D_ASSERT(drbd_interval_empty(&req->i));
 
-	if (!get_net_conf(mdev->tconn))
-		return 0;
-
 	i = drbd_find_overlap(&mdev->write_requests, sector, size);
 	if (i) {
 		dev_alert(DEV, "%s[%u] Concurrent %s write detected! "
@@ -340,17 +337,9 @@ static int _req_conflicts(struct drbd_request *req)
 		      i->local ? "local" : "remote",
 		      (unsigned long long)sector, size,
 		      (unsigned long long)i->sector, i->size);
-		goto out_conflict;
+		return 1;
 	}
-
-	/* this is like it should be, and what we expected.
-	 * our users do behave after all... */
-	put_net_conf(mdev->tconn);
 	return 0;
-
-out_conflict:
-	put_net_conf(mdev->tconn);
-	return 1;
 }
 
 /* obviously this could be coded as many single functions
-- 
1.7.4.1


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

* [PATCH 053/118] drbd: Defer new writes when detecting conflicting writes
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (51 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 052/118] drbd: Remove unnecessary reference counting left-over Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 054/118] drbd: Make the peer_seq updating code more obvious Philipp Reisner
                   ` (66 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Before submitting a new local write request, wait for any conflicting
local or remote requests to complete.

We could assume that the new request occurred first and that the
conflicting requests overwrote it (and therefore discard the new
reques), but we know for sure that the new request occurred after the
conflicting requests and so this behavior would we weird.  We would also
end up with the wrong result if the new request is not fully contained
within the conflicting requests.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_req.c |  103 +++++++++++++++-------------------------
 1 files changed, 39 insertions(+), 64 deletions(-)

diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index e11ea47..6bcf417 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -300,48 +300,6 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
 		_req_may_be_done(req, m);
 }
 
-/*
- * checks whether there was an overlapping request
- * or ee already registered.
- *
- * if so, return 1, in which case this request is completed on the spot,
- * without ever being submitted or send.
- *
- * return 0 if it is ok to submit this request.
- *
- * NOTE:
- * paranoia: assume something above us is broken, and issues different write
- * requests for the same block simultaneously...
- *
- * To ensure these won't be reordered differently on both nodes, resulting in
- * diverging data sets, we discard the later one(s). Not that this is supposed
- * to happen, but this is the rationale why we also have to check for
- * conflicting requests with local origin, and why we have to do so regardless
- * of whether we allowed multiple primaries.
- */
-static int _req_conflicts(struct drbd_request *req)
-{
-	struct drbd_conf *mdev = req->mdev;
-	const sector_t sector = req->i.sector;
-	const int size = req->i.size;
-	struct drbd_interval *i;
-
-	D_ASSERT(drbd_interval_empty(&req->i));
-
-	i = drbd_find_overlap(&mdev->write_requests, sector, size);
-	if (i) {
-		dev_alert(DEV, "%s[%u] Concurrent %s write detected! "
-		      "[DISCARD L] new: %llus +%u; "
-		      "pending: %llus +%u\n",
-		      current->comm, current->pid,
-		      i->local ? "local" : "remote",
-		      (unsigned long long)sector, size,
-		      (unsigned long long)i->sector, i->size);
-		return 1;
-	}
-	return 0;
-}
-
 /* obviously this could be coded as many single functions
  * instead of one huge switch,
  * or by putting the code directly in the respective locations
@@ -721,6 +679,34 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s
 	return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
 }
 
+/*
+ * complete_conflicting_writes  -  wait for any conflicting write requests
+ *
+ * The write_requests tree contains all active write requests which we
+ * currently know about.  Wait for any requests to complete which conflict with
+ * the new one.
+ */
+static int complete_conflicting_writes(struct drbd_conf *mdev,
+				       sector_t sector, int size)
+{
+	for(;;) {
+		DEFINE_WAIT(wait);
+		struct drbd_interval *i;
+
+		i = drbd_find_overlap(&mdev->write_requests, sector, size);
+		if (!i)
+			return 0;
+		i->waiting = true;
+		prepare_to_wait(&mdev->misc_wait, &wait, TASK_INTERRUPTIBLE);
+		spin_unlock_irq(&mdev->tconn->req_lock);
+		schedule();
+		finish_wait(&mdev->misc_wait, &wait);
+		spin_lock_irq(&mdev->tconn->req_lock);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+}
+
 static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
 {
 	const int rw = bio_rw(bio);
@@ -729,7 +715,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
 	struct drbd_tl_epoch *b = NULL;
 	struct drbd_request *req;
 	int local, remote, send_oos = 0;
-	int err = -EIO;
+	int err;
 	int ret = 0;
 
 	/* allocate outside of all locks; */
@@ -799,6 +785,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
 	if (!(local || remote) && !is_susp(mdev->state)) {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
+		err = -EIO;
 		goto fail_free_complete;
 	}
 
@@ -823,6 +810,14 @@ allocate_barrier:
 	/* GOOD, everything prepared, grab the spin_lock */
 	spin_lock_irq(&mdev->tconn->req_lock);
 
+	if (rw == WRITE) {
+		err = complete_conflicting_writes(mdev, sector, size);
+		if (err) {
+			spin_unlock_irq(&mdev->tconn->req_lock);
+			goto fail_free_complete;
+		}
+	}
+
 	if (is_susp(mdev->state)) {
 		/* If we got suspended, use the retry mechanism of
 		   generic_make_request() to restart processing of this
@@ -843,6 +838,7 @@ allocate_barrier:
 		if (!(local || remote)) {
 			dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
 			spin_unlock_irq(&mdev->tconn->req_lock);
+			err = -EIO;
 			goto fail_free_complete;
 		}
 	}
@@ -903,12 +899,6 @@ allocate_barrier:
 	if (local)
 		_req_mod(req, TO_BE_SUBMITTED);
 
-	/* check this request on the collision detection hash tables.
-	 * if we have a conflict, just complete it here.
-	 * THINK do we want to check reads, too? (I don't think so...) */
-	if (rw == WRITE && _req_conflicts(req))
-		goto fail_conflicting;
-
 	list_add_tail(&req->tl_requests, &mdev->tconn->newest_tle->requests);
 
 	/* NOTE remote first: to get the concurrent write detection right,
@@ -975,21 +965,6 @@ allocate_barrier:
 
 	return 0;
 
-fail_conflicting:
-	/* this is a conflicting request.
-	 * even though it may have been only _partially_
-	 * overlapping with one of the currently pending requests,
-	 * without even submitting or sending it, we will
-	 * pretend that it was successfully served right now.
-	 */
-	_drbd_end_io_acct(mdev, req);
-	spin_unlock_irq(&mdev->tconn->req_lock);
-	if (remote)
-		dec_ap_pending(mdev);
-	/* THINK: do we want to fail it (-EIO), or pretend success?
-	 * this pretends success. */
-	err = 0;
-
 fail_free_complete:
 	if (req->rq_state & RQ_IN_ACT_LOG)
 		drbd_al_complete_io(mdev, sector);
-- 
1.7.4.1


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

* [PATCH 054/118] drbd: Make the peer_seq updating code more obvious
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (52 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 053/118] drbd: Defer new writes when detecting conflicting writes Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 055/118] drbd: Improve the drbd_find_overlap() documentation Philipp Reisner
                   ` (65 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Make it more clear that update_peer_seq() is supposed to wake up the
seq_wait queue whenever the sequence number changes.

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cde48f3..654c1c9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1654,15 +1654,15 @@ static u32 seq_max(u32 a, u32 b)
 	return seq_greater(a, b) ? a : b;
 }
 
-static void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq)
+static void update_peer_seq(struct drbd_conf *mdev, unsigned int peer_seq)
 {
-	unsigned int m;
+	unsigned int old_peer_seq;
 
 	spin_lock(&mdev->peer_seq_lock);
-	m = seq_max(mdev->peer_seq, new_seq);
-	mdev->peer_seq = m;
+	old_peer_seq = mdev->peer_seq;
+	mdev->peer_seq = seq_max(mdev->peer_seq, peer_seq);
 	spin_unlock(&mdev->peer_seq_lock);
-	if (m == new_seq)
+	if (old_peer_seq != peer_seq)
 		wake_up(&mdev->seq_wait);
 }
 
-- 
1.7.4.1


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

* [PATCH 055/118] drbd: Improve the drbd_find_overlap() documentation
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (53 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 054/118] drbd: Make the peer_seq updating code more obvious Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 056/118] drbd: Remove unused variable in struct drbd_conf Philipp Reisner
                   ` (64 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

From: Andreas Gruenbacher <agruen@linbit.com>

Describe how to reach any further overlapping intervals from the first
overlap found.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_interval.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/block/drbd/drbd_interval.c b/drivers/block/drbd/drbd_interval.c
index 0d17eaa..14dbe2d 100644
--- a/drivers/block/drbd/drbd_interval.c
+++ b/drivers/block/drbd/drbd_interval.c
@@ -122,9 +122,11 @@ drbd_remove_interval(struct rb_root *root, struct drbd_interval *this)
  * @sector:	start sector
  * @size:	size, aligned to 512 bytes
  *
- * Returns the interval overlapping with [sector, sector + size), or NULL.
- * When there is more than one overlapping interval in the tree, the interval
- * with the lowest start sector is returned.
+ * Returns an interval overlapping with [sector, sector + size), or NULL if
+ * there is none.  When there is more than one overlapping interval in the
+ * tree, the interval with the lowest start sector is returned, and all other
+ * overlapping intervals will be on the right side of the tree, reachable with
+ * rb_next().
  */
 struct drbd_interval *
 drbd_find_overlap(struct rb_root *root, sector_t sector, unsigned int size)
-- 
1.7.4.1


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

* [PATCH 056/118] drbd: Remove unused variable in struct drbd_conf
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (54 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 055/118] drbd: Improve the drbd_find_overlap() documentation Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 057/118] drbd: Rename struct drbd_epoch_entry to struct drbd_peer_request Philipp Reisner
                   ` (63 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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 |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index faa7cbd..c730f20 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1045,9 +1045,6 @@ struct drbd_conf {
 	struct list_head read_ee;   /* IO in progress (any read) */
 	struct list_head net_ee;    /* zero-copy network send in progress */
 
-	/* this one is protected by ee_lock, single thread */
-	struct drbd_epoch_entry *last_write_w_barrier;
-
 	int next_barrier_nr;
 	struct list_head resync_reads;
 	atomic_t pp_in_use;		/* allocated from page pool */
-- 
1.7.4.1


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

* [PATCH 057/118] drbd: Rename struct drbd_epoch_entry to struct drbd_peer_request
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (55 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 056/118] drbd: Remove unused variable in struct drbd_conf Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 058/118] drbd: Clean up some left-overs Philipp Reisner
                   ` (62 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |   37 ++++++++++++---------------
 drivers/block/drbd/drbd_main.c     |    8 +++---
 drivers/block/drbd/drbd_nl.c       |    7 ++---
 drivers/block/drbd/drbd_receiver.c |   48 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_worker.c   |   25 +++++++++---------
 5 files changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c730f20..37b3488 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -707,7 +707,7 @@ struct digest_info {
 	void *digest;
 };
 
-struct drbd_epoch_entry {
+struct drbd_peer_request {
 	struct drbd_work w;
 	struct drbd_epoch *epoch; /* for writes */
 	struct drbd_conf *mdev;
@@ -1194,8 +1194,8 @@ extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd,
 extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc);
 extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
 			u32 set_size);
-extern int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
-			 struct drbd_epoch_entry *e);
+extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet,
+			 struct drbd_peer_request *);
 extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd,
 			    struct p_block_req *rp);
 extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
@@ -1203,8 +1203,8 @@ extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packet cmd,
 extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packet cmd,
 			    sector_t sector, int blksize, u64 block_id);
 extern int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req);
-extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
-			   struct drbd_epoch_entry *e);
+extern int drbd_send_block(struct drbd_conf *, enum drbd_packet,
+			   struct drbd_peer_request *);
 extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req);
 extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
 			      sector_t sector, int size, u64 block_id);
@@ -1500,7 +1500,8 @@ static inline void ov_oos_print(struct drbd_conf *mdev)
 
 
 extern void drbd_csum_bio(struct drbd_conf *, struct crypto_hash *, struct bio *, void *);
-extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *, struct drbd_epoch_entry *, void *);
+extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *,
+			 struct drbd_peer_request *, void *);
 /* worker callbacks */
 extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int);
 extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int);
@@ -1527,16 +1528,14 @@ extern void start_resync_timer_fn(unsigned long data);
 
 /* drbd_receiver.c */
 extern int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector);
-extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
-		const unsigned rw, const int fault_type);
+extern int drbd_submit_ee(struct drbd_conf *, struct drbd_peer_request *,
+			  const unsigned, const int);
 extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list);
-extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
-					    u64 id,
-					    sector_t sector,
-					    unsigned int data_size,
-					    gfp_t gfp_mask) __must_hold(local);
-extern void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
-		int is_net);
+extern struct drbd_peer_request *drbd_alloc_ee(struct drbd_conf *,
+					       u64, sector_t, unsigned int,
+					       gfp_t) __must_hold(local);
+extern void drbd_free_some_ee(struct drbd_conf *, struct drbd_peer_request *,
+			      int);
 #define drbd_free_ee(m,e)	drbd_free_some_ee(m, e, 0)
 #define drbd_free_net_ee(m,e)	drbd_free_some_ee(m, e, 1)
 extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev,
@@ -1627,10 +1626,8 @@ void drbd_nl_cleanup(void);
 int __init drbd_nl_init(void);
 void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state);
 void drbd_bcast_sync_progress(struct drbd_conf *mdev);
-void drbd_bcast_ee(struct drbd_conf *mdev,
-		const char *reason, const int dgs,
-		const char* seen_hash, const char* calc_hash,
-		const struct drbd_epoch_entry* e);
+void drbd_bcast_ee(struct drbd_conf *, const char *, const int, const char *,
+		   const char *, const struct drbd_peer_request *);
 
 
 /**
@@ -1713,7 +1710,7 @@ static inline int drbd_bio_has_active_page(struct bio *bio)
 	return 0;
 }
 
-static inline int drbd_ee_has_active_page(struct drbd_epoch_entry *e)
+static inline int drbd_ee_has_active_page(struct drbd_peer_request *e)
 {
 	struct page *page = e->pages;
 	page_chain_for_each(page) {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a2417e4..9e8cc1c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2434,7 +2434,7 @@ int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd,
  * @e:		Epoch entry.
  */
 int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
-		  struct drbd_epoch_entry *e)
+		  struct drbd_peer_request *e)
 {
 	return _drbd_send_ack(mdev, cmd,
 			      cpu_to_be64(e->i.sector),
@@ -2641,7 +2641,7 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
 	return 1;
 }
 
-static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
+static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_peer_request *e)
 {
 	struct page *page = e->pages;
 	unsigned len = e->i.size;
@@ -2747,7 +2747,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
  *  C_SYNC_SOURCE -> C_SYNC_TARGET         (P_RS_DATA_REPLY)
  */
 int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
-		    struct drbd_epoch_entry *e)
+		    struct drbd_peer_request *e)
 {
 	int ok;
 	struct p_data p;
@@ -3147,7 +3147,7 @@ static int drbd_create_mempools(void)
 		goto Enomem;
 
 	drbd_ee_cache = kmem_cache_create(
-		"drbd_ee", sizeof(struct drbd_epoch_entry), 0, 0, NULL);
+		"drbd_ee", sizeof(struct drbd_peer_request), 0, 0, NULL);
 	if (drbd_ee_cache == NULL)
 		goto Enomem;
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 8b8894e..ee00ffa 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2443,10 +2443,9 @@ void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name)
 	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
 }
 
-void drbd_bcast_ee(struct drbd_conf *mdev,
-		const char *reason, const int dgs,
-		const char* seen_hash, const char* calc_hash,
-		const struct drbd_epoch_entry* e)
+void drbd_bcast_ee(struct drbd_conf *mdev, const char *reason, const int dgs,
+		   const char *seen_hash, const char *calc_hash,
+			   const struct drbd_peer_request *e)
 {
 	struct cn_msg *cn_reply;
 	struct drbd_nl_cfg_reply *reply;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 654c1c9..7829656 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -189,7 +189,7 @@ static struct page *drbd_pp_first_pages_or_try_alloc(struct drbd_conf *mdev, int
 
 static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed)
 {
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 	struct list_head *le, *tle;
 
 	/* The EEs are always appended to the end of the list. Since
@@ -198,7 +198,7 @@ static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed
 	   stop to examine the list... */
 
 	list_for_each_safe(le, tle, &mdev->net_ee) {
-		e = list_entry(le, struct drbd_epoch_entry, w.list);
+		e = list_entry(le, struct drbd_peer_request, w.list);
 		if (drbd_ee_has_active_page(e))
 			break;
 		list_move(le, to_be_freed);
@@ -208,7 +208,7 @@ static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed
 static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev)
 {
 	LIST_HEAD(reclaimed);
-	struct drbd_epoch_entry *e, *t;
+	struct drbd_peer_request *e, *t;
 
 	spin_lock_irq(&mdev->tconn->req_lock);
 	reclaim_net_ee(mdev, &reclaimed);
@@ -309,13 +309,11 @@ You must not have the req_lock:
  drbd_wait_ee_list_empty()
 */
 
-struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
-				     u64 id,
-				     sector_t sector,
-				     unsigned int data_size,
-				     gfp_t gfp_mask) __must_hold(local)
+struct drbd_peer_request *
+drbd_alloc_ee(struct drbd_conf *mdev, u64 id, sector_t sector,
+	      unsigned int data_size, gfp_t gfp_mask) __must_hold(local)
 {
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 	struct page *page;
 	unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
 
@@ -357,7 +355,8 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
 	return NULL;
 }
 
-void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, int is_net)
+void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_peer_request *e,
+		       int is_net)
 {
 	if (e->flags & EE_HAS_DIGEST)
 		kfree(e->digest);
@@ -370,7 +369,7 @@ void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, int i
 int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 {
 	LIST_HEAD(work_list);
-	struct drbd_epoch_entry *e, *t;
+	struct drbd_peer_request *e, *t;
 	int count = 0;
 	int is_net = list == &mdev->net_ee;
 
@@ -399,7 +398,7 @@ static int drbd_process_done_ee(struct drbd_conf *mdev)
 {
 	LIST_HEAD(work_list);
 	LIST_HEAD(reclaimed);
-	struct drbd_epoch_entry *e, *t;
+	struct drbd_peer_request *e, *t;
 	int ok = (mdev->state.conn >= C_WF_REPORT_PARAMS);
 
 	spin_lock_irq(&mdev->tconn->req_lock);
@@ -1104,8 +1103,8 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
  *  on certain Xen deployments.
  */
 /* TODO allocate from our own bio_set. */
-int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
-		const unsigned rw, const int fault_type)
+int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_peer_request *e,
+		   const unsigned rw, const int fault_type)
 {
 	struct bio *bios = NULL;
 	struct bio *bio;
@@ -1180,7 +1179,7 @@ fail:
 }
 
 static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
-					     struct drbd_epoch_entry *e)
+					     struct drbd_peer_request *e)
 {
 	struct drbd_interval *i = &e->i;
 
@@ -1266,11 +1265,12 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 /* used from receive_RSDataReply (recv_resync_read)
  * and from receive_Data */
-static struct drbd_epoch_entry *
-read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __must_hold(local)
+static struct drbd_peer_request *
+read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
+	      int data_size) __must_hold(local)
 {
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 	struct page *page;
 	int dgs, ds, rr;
 	void *dig_in = mdev->tconn->int_dig_in;
@@ -1449,7 +1449,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
  * drbd_process_done_ee() by asender only */
 static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
-	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
 	sector_t sector = e->i.sector;
 	int ok;
 
@@ -1471,7 +1471,7 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u
 
 static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_size) __releases(local)
 {
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 
 	e = read_in_block(mdev, ID_SYNCER, sector, data_size);
 	if (!e)
@@ -1586,7 +1586,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
  */
 static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
 	sector_t sector = e->i.sector;
 	int ok = 1, pcmd;
 
@@ -1623,7 +1623,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
 static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
-	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
 	int ok = 1;
 
 	D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
@@ -1735,7 +1735,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 			unsigned int data_size)
 {
 	sector_t sector;
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 	struct p_data *p = &mdev->tconn->data.rbuf.data;
 	int rw = WRITE;
 	u32 dp_flags;
@@ -2019,7 +2019,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 {
 	sector_t sector;
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 	struct digest_info *di = NULL;
 	int size, verb;
 	unsigned int fault_type;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 0359600..06628d1 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -80,7 +80,7 @@ void drbd_md_io_complete(struct bio *bio, int error)
 /* reads on behalf of the partner,
  * "submitted" by the receiver
  */
-void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
+void drbd_endio_read_sec_final(struct drbd_peer_request *e) __releases(local)
 {
 	unsigned long flags = 0;
 	struct drbd_conf *mdev = e->mdev;
@@ -100,7 +100,7 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
 
 /* writes on behalf of the partner, or resync writes,
  * "submitted" by the receiver, final stage.  */
-static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local)
+static void drbd_endio_write_sec_final(struct drbd_peer_request *e) __releases(local)
 {
 	unsigned long flags = 0;
 	struct drbd_conf *mdev = e->mdev;
@@ -154,7 +154,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
  */
 void drbd_endio_sec(struct bio *bio, int error)
 {
-	struct drbd_epoch_entry *e = bio->bi_private;
+	struct drbd_peer_request *e = bio->bi_private;
 	struct drbd_conf *mdev = e->mdev;
 	int uptodate = bio_flagged(bio, BIO_UPTODATE);
 	int is_write = bio_data_dir(bio) == WRITE;
@@ -247,7 +247,8 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return w_send_read_req(mdev, w, 0);
 }
 
-void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm, struct drbd_epoch_entry *e, void *digest)
+void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm,
+		  struct drbd_peer_request *e, void *digest)
 {
 	struct hash_desc desc;
 	struct scatterlist sg;
@@ -297,7 +298,7 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
 /* TODO merge common code with w_e_end_ov_req */
 int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -344,7 +345,7 @@ out:
 
 static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 {
-	struct drbd_epoch_entry *e;
+	struct drbd_peer_request *e;
 
 	if (!get_ldev(mdev))
 		return -EIO;
@@ -900,7 +901,7 @@ out:
 }
 
 /* helper */
-static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
+static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_peer_request *e)
 {
 	if (drbd_ee_has_active_page(e)) {
 		/* This might happen if sendpage() has not finished */
@@ -923,7 +924,7 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_ent
  */
 int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -959,7 +960,7 @@ int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
  */
 int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -1007,7 +1008,7 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
 int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	struct digest_info *di;
 	int digest_size;
 	void *digest = NULL;
@@ -1070,7 +1071,7 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 /* TODO merge common code with w_e_send_csum */
 int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	sector_t sector = e->i.sector;
 	unsigned int size = e->i.size;
 	int digest_size;
@@ -1127,7 +1128,7 @@ void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size)
 
 int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
 	struct digest_info *di;
 	void *digest;
 	sector_t sector = e->i.sector;
-- 
1.7.4.1


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

* [PATCH 058/118] drbd: Clean up some left-overs
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (56 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 057/118] drbd: Rename struct drbd_epoch_entry to struct drbd_peer_request Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 059/118] drbd: Update some comments Philipp Reisner
                   ` (61 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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 |   13 ++-----------
 1 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 37b3488..f39c279 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -668,15 +668,6 @@ struct drbd_tl_epoch {
 	int n_writes;	/* number of requests attached before this barrier */
 };
 
-struct drbd_request;
-
-/* These Tl_epoch_entries may be in one of 6 lists:
-   active_ee .. data packet being written
-   sync_ee   .. syncer block being written
-   done_ee   .. block written, need to send P_WRITE_ACK
-   read_ee   .. [RS]P_DATA_REQUEST being read
-*/
-
 struct drbd_epoch {
 	struct list_head list;
 	unsigned int barrier_nr;
@@ -1041,8 +1032,8 @@ struct drbd_conf {
 	enum write_ordering_e write_ordering;
 	struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */
 	struct list_head sync_ee;   /* IO in progress (P_RS_DATA_REPLY gets written to disk) */
-	struct list_head done_ee;   /* send ack */
-	struct list_head read_ee;   /* IO in progress (any read) */
+	struct list_head done_ee;   /* need to send P_WRITE_ACK */
+	struct list_head read_ee;   /* [RS]P_DATA_REQUEST being read */
 	struct list_head net_ee;    /* zero-copy network send in progress */
 
 	int next_barrier_nr;
-- 
1.7.4.1


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

* [PATCH 059/118] drbd: Update some comments
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (57 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 058/118] drbd: Clean up some left-overs Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 060/118] drbd: Local variable renames: e -> peer_req Philipp Reisner
                   ` (60 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    4 ++--
 drivers/block/drbd/drbd_main.c     |    2 +-
 drivers/block/drbd/drbd_receiver.c |    4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index f39c279..2cebdd6 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -727,7 +727,7 @@ enum {
 	 * we need to resubmit without the barrier flag. */
 	__EE_RESUBMITTED,
 
-	/* we may have several bios per epoch entry.
+	/* we may have several bios per peer request.
 	 * if any of those fail, we set this flag atomically
 	 * from the endio callback */
 	__EE_WAS_ERROR,
@@ -1422,7 +1422,7 @@ extern void drbd_bm_unlock(struct drbd_conf *mdev);
 /* drbd_main.c */
 
 extern struct kmem_cache *drbd_request_cache;
-extern struct kmem_cache *drbd_ee_cache;	/* epoch entries */
+extern struct kmem_cache *drbd_ee_cache;	/* peer requests */
 extern struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
 extern struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
 extern mempool_t *drbd_request_mempool;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9e8cc1c..964f76e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -135,7 +135,7 @@ struct drbd_conf **minor_table;
 struct list_head drbd_tconns;  /* list of struct drbd_tconn */
 
 struct kmem_cache *drbd_request_cache;
-struct kmem_cache *drbd_ee_cache;	/* epoch entries */
+struct kmem_cache *drbd_ee_cache;	/* peer requests */
 struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
 struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
 mempool_t *drbd_request_mempool;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 7829656..5c4c260 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1089,7 +1089,7 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
 /**
  * drbd_submit_ee()
  * @mdev:	DRBD device.
- * @e:		epoch entry
+ * @e:		peer request
  * @rw:		flag field, see bio->bi_rw
  *
  * May spread the pages to multiple bios,
@@ -1186,7 +1186,7 @@ static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
 	drbd_remove_interval(&mdev->write_requests, i);
 	drbd_clear_interval(i);
 
-	/* Wake up any processes waiting for this epoch entry to complete.  */
+	/* Wake up any processes waiting for this peer request to complete.  */
 	if (i->waiting)
 		wake_up(&mdev->misc_wait);
 }
-- 
1.7.4.1


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

* [PATCH 060/118] drbd: Local variable renames: e -> peer_req
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (58 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 059/118] drbd: Update some comments Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 061/118] drbd: Moved the state functions into its own source file Philipp Reisner
                   ` (59 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 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      |    4 +-
 drivers/block/drbd/drbd_main.c     |   36 +++---
 drivers/block/drbd/drbd_nl.c       |   18 ++-
 drivers/block/drbd/drbd_receiver.c |  256 ++++++++++++++++++------------------
 drivers/block/drbd/drbd_worker.c   |  197 ++++++++++++++--------------
 5 files changed, 259 insertions(+), 252 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2cebdd6..f934aa2 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1701,9 +1701,9 @@ static inline int drbd_bio_has_active_page(struct bio *bio)
 	return 0;
 }
 
-static inline int drbd_ee_has_active_page(struct drbd_peer_request *e)
+static inline int drbd_ee_has_active_page(struct drbd_peer_request *peer_req)
 {
-	struct page *page = e->pages;
+	struct page *page = peer_req->pages;
 	page_chain_for_each(page) {
 		if (page_count(page) > 1)
 			return 1;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 964f76e..44be1f2 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2429,17 +2429,17 @@ int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 /**
  * drbd_send_ack() - Sends an ack packet
- * @mdev:	DRBD device.
- * @cmd:	Packet command code.
- * @e:		Epoch entry.
+ * @mdev:	DRBD device
+ * @cmd:	packet command code
+ * @peer_req:	peer request
  */
 int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packet cmd,
-		  struct drbd_peer_request *e)
+		  struct drbd_peer_request *peer_req)
 {
 	return _drbd_send_ack(mdev, cmd,
-			      cpu_to_be64(e->i.sector),
-			      cpu_to_be32(e->i.size),
-			      e->block_id);
+			      cpu_to_be64(peer_req->i.sector),
+			      cpu_to_be32(peer_req->i.size),
+			      peer_req->block_id);
 }
 
 /* This function misuses the block_id field to signal if the blocks
@@ -2641,10 +2641,12 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
 	return 1;
 }
 
-static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_peer_request *e)
+static int _drbd_send_zc_ee(struct drbd_conf *mdev,
+			    struct drbd_peer_request *peer_req)
 {
-	struct page *page = e->pages;
-	unsigned len = e->i.size;
+	struct page *page = peer_req->pages;
+	unsigned len = peer_req->i.size;
+
 	/* hint all but last page with MSG_MORE */
 	page_chain_for_each(page) {
 		unsigned l = min_t(unsigned, len, PAGE_SIZE);
@@ -2747,7 +2749,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
  *  C_SYNC_SOURCE -> C_SYNC_TARGET         (P_RS_DATA_REPLY)
  */
 int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
-		    struct drbd_peer_request *e)
+		    struct drbd_peer_request *peer_req)
 {
 	int ok;
 	struct p_data p;
@@ -2757,9 +2759,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	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 + e->i.size);
-	p.sector   = cpu_to_be64(e->i.sector);
-	p.block_id = e->block_id;
+	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.
@@ -2772,11 +2776,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	ok = sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
 	if (ok && dgs) {
 		dgb = mdev->tconn->int_dig_out;
-		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, e, dgb);
+		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, peer_req, dgb);
 		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok)
-		ok = _drbd_send_zc_ee(mdev, e);
+		ok = _drbd_send_zc_ee(mdev, peer_req);
 
 	drbd_put_data_sock(mdev);
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index ee00ffa..e30d52b 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2445,7 +2445,7 @@ void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name)
 
 void drbd_bcast_ee(struct drbd_conf *mdev, const char *reason, const int dgs,
 		   const char *seen_hash, const char *calc_hash,
-			   const struct drbd_peer_request *e)
+			   const struct drbd_peer_request *peer_req)
 {
 	struct cn_msg *cn_reply;
 	struct drbd_nl_cfg_reply *reply;
@@ -2453,7 +2453,7 @@ void drbd_bcast_ee(struct drbd_conf *mdev, const char *reason, const int dgs,
 	struct page *page;
 	unsigned len;
 
-	if (!e)
+	if (!peer_req)
 		return;
 	if (!reason || !reason[0])
 		return;
@@ -2472,8 +2472,10 @@ void drbd_bcast_ee(struct drbd_conf *mdev, const char *reason, const int dgs,
 		GFP_NOIO);
 
 	if (!cn_reply) {
-		dev_err(DEV, "could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n",
-				(unsigned long long)e->i.sector, e->i.size);
+		dev_err(DEV, "could not kmalloc buffer for drbd_bcast_ee, "
+			     "sector %llu, size %u\n",
+			(unsigned long long)peer_req->i.sector,
+			peer_req->i.size);
 		return;
 	}
 
@@ -2483,15 +2485,15 @@ void drbd_bcast_ee(struct drbd_conf *mdev, const char *reason, const int dgs,
 	tl = tl_add_str(tl, T_dump_ee_reason, reason);
 	tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs);
 	tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs);
-	tl = tl_add_int(tl, T_ee_sector, &e->i.sector);
-	tl = tl_add_int(tl, T_ee_block_id, &e->block_id);
+	tl = tl_add_int(tl, T_ee_sector, &peer_req->i.sector);
+	tl = tl_add_int(tl, T_ee_block_id, &peer_req->block_id);
 
 	/* dump the first 32k */
-	len = min_t(unsigned, e->i.size, 32 << 10);
+	len = min_t(unsigned, peer_req->i.size, 32 << 10);
 	put_unaligned(T_ee_data, tl++);
 	put_unaligned(len, tl++);
 
-	page = e->pages;
+	page = peer_req->pages;
 	page_chain_for_each(page) {
 		void *d = kmap_atomic(page, KM_USER0);
 		unsigned l = min_t(unsigned, len, PAGE_SIZE);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 5c4c260..3f0f41f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -189,7 +189,7 @@ static struct page *drbd_pp_first_pages_or_try_alloc(struct drbd_conf *mdev, int
 
 static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed)
 {
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 	struct list_head *le, *tle;
 
 	/* The EEs are always appended to the end of the list. Since
@@ -198,8 +198,8 @@ static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed
 	   stop to examine the list... */
 
 	list_for_each_safe(le, tle, &mdev->net_ee) {
-		e = list_entry(le, struct drbd_peer_request, w.list);
-		if (drbd_ee_has_active_page(e))
+		peer_req = list_entry(le, struct drbd_peer_request, w.list);
+		if (drbd_ee_has_active_page(peer_req))
 			break;
 		list_move(le, to_be_freed);
 	}
@@ -208,14 +208,14 @@ static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed
 static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev)
 {
 	LIST_HEAD(reclaimed);
-	struct drbd_peer_request *e, *t;
+	struct drbd_peer_request *peer_req, *t;
 
 	spin_lock_irq(&mdev->tconn->req_lock);
 	reclaim_net_ee(mdev, &reclaimed);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	list_for_each_entry_safe(e, t, &reclaimed, w.list)
-		drbd_free_net_ee(mdev, e);
+	list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
+		drbd_free_net_ee(mdev, peer_req);
 }
 
 /**
@@ -313,15 +313,15 @@ struct drbd_peer_request *
 drbd_alloc_ee(struct drbd_conf *mdev, u64 id, sector_t sector,
 	      unsigned int data_size, gfp_t gfp_mask) __must_hold(local)
 {
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 	struct page *page;
 	unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
 
 	if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE))
 		return NULL;
 
-	e = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM);
-	if (!e) {
+	peer_req = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM);
+	if (!peer_req) {
 		if (!(gfp_mask & __GFP_NOWARN))
 			dev_err(DEV, "alloc_ee: Allocation of an EE failed\n");
 		return NULL;
@@ -331,45 +331,45 @@ drbd_alloc_ee(struct drbd_conf *mdev, u64 id, sector_t sector,
 	if (!page)
 		goto fail;
 
-	drbd_clear_interval(&e->i);
-	e->i.size = data_size;
-	e->i.sector = sector;
-	e->i.local = false;
-	e->i.waiting = false;
-
-	e->epoch = NULL;
-	e->mdev = mdev;
-	e->pages = page;
-	atomic_set(&e->pending_bios, 0);
-	e->flags = 0;
+	drbd_clear_interval(&peer_req->i);
+	peer_req->i.size = data_size;
+	peer_req->i.sector = sector;
+	peer_req->i.local = false;
+	peer_req->i.waiting = false;
+
+	peer_req->epoch = NULL;
+	peer_req->mdev = mdev;
+	peer_req->pages = page;
+	atomic_set(&peer_req->pending_bios, 0);
+	peer_req->flags = 0;
 	/*
 	 * The block_id is opaque to the receiver.  It is not endianness
 	 * converted, and sent back to the sender unchanged.
 	 */
-	e->block_id = id;
+	peer_req->block_id = id;
 
-	return e;
+	return peer_req;
 
  fail:
-	mempool_free(e, drbd_ee_mempool);
+	mempool_free(peer_req, drbd_ee_mempool);
 	return NULL;
 }
 
-void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_peer_request *e,
+void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_peer_request *peer_req,
 		       int is_net)
 {
-	if (e->flags & EE_HAS_DIGEST)
-		kfree(e->digest);
-	drbd_pp_free(mdev, e->pages, is_net);
-	D_ASSERT(atomic_read(&e->pending_bios) == 0);
-	D_ASSERT(drbd_interval_empty(&e->i));
-	mempool_free(e, drbd_ee_mempool);
+	if (peer_req->flags & EE_HAS_DIGEST)
+		kfree(peer_req->digest);
+	drbd_pp_free(mdev, peer_req->pages, is_net);
+	D_ASSERT(atomic_read(&peer_req->pending_bios) == 0);
+	D_ASSERT(drbd_interval_empty(&peer_req->i));
+	mempool_free(peer_req, drbd_ee_mempool);
 }
 
 int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 {
 	LIST_HEAD(work_list);
-	struct drbd_peer_request *e, *t;
+	struct drbd_peer_request *peer_req, *t;
 	int count = 0;
 	int is_net = list == &mdev->net_ee;
 
@@ -377,8 +377,8 @@ int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 	list_splice_init(list, &work_list);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	list_for_each_entry_safe(e, t, &work_list, w.list) {
-		drbd_free_some_ee(mdev, e, is_net);
+	list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
+		drbd_free_some_ee(mdev, peer_req, is_net);
 		count++;
 	}
 	return count;
@@ -398,7 +398,7 @@ static int drbd_process_done_ee(struct drbd_conf *mdev)
 {
 	LIST_HEAD(work_list);
 	LIST_HEAD(reclaimed);
-	struct drbd_peer_request *e, *t;
+	struct drbd_peer_request *peer_req, *t;
 	int ok = (mdev->state.conn >= C_WF_REPORT_PARAMS);
 
 	spin_lock_irq(&mdev->tconn->req_lock);
@@ -406,17 +406,17 @@ static int drbd_process_done_ee(struct drbd_conf *mdev)
 	list_splice_init(&mdev->done_ee, &work_list);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	list_for_each_entry_safe(e, t, &reclaimed, w.list)
-		drbd_free_net_ee(mdev, e);
+	list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
+		drbd_free_net_ee(mdev, peer_req);
 
 	/* possible callbacks here:
 	 * e_end_block, and e_end_resync_block, e_send_discard_ack.
 	 * all ignore the last argument.
 	 */
-	list_for_each_entry_safe(e, t, &work_list, w.list) {
+	list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
 		/* list_del not necessary, next/prev members not touched */
-		ok = e->w.cb(mdev, &e->w, !ok) && ok;
-		drbd_free_ee(mdev, e);
+		ok = peer_req->w.cb(mdev, &peer_req->w, !ok) && ok;
+		drbd_free_ee(mdev, peer_req);
 	}
 	wake_up(&mdev->ee_wait);
 
@@ -1089,7 +1089,7 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
 /**
  * drbd_submit_ee()
  * @mdev:	DRBD device.
- * @e:		peer request
+ * @peer_req:	peer request
  * @rw:		flag field, see bio->bi_rw
  *
  * May spread the pages to multiple bios,
@@ -1103,14 +1103,14 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
  *  on certain Xen deployments.
  */
 /* TODO allocate from our own bio_set. */
-int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_peer_request *e,
+int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_peer_request *peer_req,
 		   const unsigned rw, const int fault_type)
 {
 	struct bio *bios = NULL;
 	struct bio *bio;
-	struct page *page = e->pages;
-	sector_t sector = e->i.sector;
-	unsigned ds = e->i.size;
+	struct page *page = peer_req->pages;
+	sector_t sector = peer_req->i.sector;
+	unsigned ds = peer_req->i.size;
 	unsigned n_bios = 0;
 	unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT;
 	int err = -ENOMEM;
@@ -1125,11 +1125,11 @@ next_bio:
 		dev_err(DEV, "submit_ee: Allocation of a bio failed\n");
 		goto fail;
 	}
-	/* > e->i.sector, unless this is the first bio */
+	/* > peer_req->i.sector, unless this is the first bio */
 	bio->bi_sector = sector;
 	bio->bi_bdev = mdev->ldev->backing_bdev;
 	bio->bi_rw = rw;
-	bio->bi_private = e;
+	bio->bi_private = peer_req;
 	bio->bi_end_io = drbd_endio_sec;
 
 	bio->bi_next = bios;
@@ -1159,7 +1159,7 @@ next_bio:
 	D_ASSERT(page == NULL);
 	D_ASSERT(ds == 0);
 
-	atomic_set(&e->pending_bios, n_bios);
+	atomic_set(&peer_req->pending_bios, n_bios);
 	do {
 		bio = bios;
 		bios = bios->bi_next;
@@ -1179,9 +1179,9 @@ fail:
 }
 
 static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
-					     struct drbd_peer_request *e)
+					     struct drbd_peer_request *peer_req)
 {
-	struct drbd_interval *i = &e->i;
+	struct drbd_interval *i = &peer_req->i;
 
 	drbd_remove_interval(&mdev->write_requests, i);
 	drbd_clear_interval(i);
@@ -1270,7 +1270,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 	      int data_size) __must_hold(local)
 {
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 	struct page *page;
 	int dgs, ds, rr;
 	void *dig_in = mdev->tconn->int_dig_in;
@@ -1313,12 +1313,12 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 	/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
 	 * "criss-cross" setup, that might cause write-out on some other DRBD,
 	 * which in turn might block on the other node at this very place.  */
-	e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_NOIO);
-	if (!e)
+	peer_req = drbd_alloc_ee(mdev, id, sector, data_size, GFP_NOIO);
+	if (!peer_req)
 		return NULL;
 
 	ds = data_size;
-	page = e->pages;
+	page = peer_req->pages;
 	page_chain_for_each(page) {
 		unsigned len = min_t(int, ds, PAGE_SIZE);
 		data = kmap(page);
@@ -1329,7 +1329,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 		}
 		kunmap(page);
 		if (rr != len) {
-			drbd_free_ee(mdev, e);
+			drbd_free_ee(mdev, peer_req);
 			if (!signal_pending(current))
 				dev_warn(DEV, "short read receiving data: read %d expected %d\n",
 				rr, len);
@@ -1339,18 +1339,18 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 	}
 
 	if (dgs) {
-		drbd_csum_ee(mdev, mdev->tconn->integrity_r_tfm, e, dig_vv);
+		drbd_csum_ee(mdev, mdev->tconn->integrity_r_tfm, peer_req, dig_vv);
 		if (memcmp(dig_in, dig_vv, dgs)) {
 			dev_err(DEV, "Digest integrity check FAILED: %llus +%u\n",
 				(unsigned long long)sector, data_size);
 			drbd_bcast_ee(mdev, "digest failed",
-					dgs, dig_in, dig_vv, e);
-			drbd_free_ee(mdev, e);
+					dgs, dig_in, dig_vv, peer_req);
+			drbd_free_ee(mdev, peer_req);
 			return NULL;
 		}
 	}
 	mdev->recv_cnt += data_size>>9;
-	return e;
+	return peer_req;
 }
 
 /* drbd_drain_block() just takes a data block
@@ -1449,20 +1449,20 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
  * drbd_process_done_ee() by asender only */
 static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
-	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
-	sector_t sector = e->i.sector;
+	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
+	sector_t sector = peer_req->i.sector;
 	int ok;
 
-	D_ASSERT(drbd_interval_empty(&e->i));
+	D_ASSERT(drbd_interval_empty(&peer_req->i));
 
-	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
-		drbd_set_in_sync(mdev, sector, e->i.size);
-		ok = drbd_send_ack(mdev, P_RS_WRITE_ACK, e);
+	if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
+		drbd_set_in_sync(mdev, sector, peer_req->i.size);
+		ok = drbd_send_ack(mdev, P_RS_WRITE_ACK, peer_req);
 	} else {
 		/* Record failure to sync */
-		drbd_rs_failed_io(mdev, sector, e->i.size);
+		drbd_rs_failed_io(mdev, sector, peer_req->i.size);
 
-		ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
+		ok  = drbd_send_ack(mdev, P_NEG_ACK, peer_req);
 	}
 	dec_unacked(mdev);
 
@@ -1471,10 +1471,10 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u
 
 static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_size) __releases(local)
 {
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 
-	e = read_in_block(mdev, ID_SYNCER, sector, data_size);
-	if (!e)
+	peer_req = read_in_block(mdev, ID_SYNCER, sector, data_size);
+	if (!peer_req)
 		goto fail;
 
 	dec_rs_pending(mdev);
@@ -1483,23 +1483,23 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
 	/* corresponding dec_unacked() in e_end_resync_block()
 	 * respective _drbd_clear_done_ee */
 
-	e->w.cb = e_end_resync_block;
+	peer_req->w.cb = e_end_resync_block;
 
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_add(&e->w.list, &mdev->sync_ee);
+	list_add(&peer_req->w.list, &mdev->sync_ee);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	atomic_add(data_size >> 9, &mdev->rs_sect_ev);
-	if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0)
+	if (drbd_submit_ee(mdev, peer_req, WRITE, DRBD_FAULT_RS_WR) == 0)
 		return true;
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_del(&e->w.list);
+	list_del(&peer_req->w.list);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	drbd_free_ee(mdev, e);
+	drbd_free_ee(mdev, peer_req);
 fail:
 	put_ldev(mdev);
 	return false;
@@ -1586,21 +1586,21 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
  */
 static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
-	sector_t sector = e->i.sector;
+	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
+	sector_t sector = peer_req->i.sector;
 	int ok = 1, pcmd;
 
 	if (mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C) {
-		if (likely((e->flags & EE_WAS_ERROR) == 0)) {
+		if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
 			pcmd = (mdev->state.conn >= C_SYNC_SOURCE &&
 				mdev->state.conn <= C_PAUSED_SYNC_T &&
-				e->flags & EE_MAY_SET_IN_SYNC) ?
+				peer_req->flags & EE_MAY_SET_IN_SYNC) ?
 				P_RS_WRITE_ACK : P_WRITE_ACK;
-			ok &= drbd_send_ack(mdev, pcmd, e);
+			ok &= drbd_send_ack(mdev, pcmd, peer_req);
 			if (pcmd == P_RS_WRITE_ACK)
-				drbd_set_in_sync(mdev, sector, e->i.size);
+				drbd_set_in_sync(mdev, sector, peer_req->i.size);
 		} else {
-			ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
+			ok  = drbd_send_ack(mdev, P_NEG_ACK, peer_req);
 			/* we expect it to be marked out of sync anyways...
 			 * maybe assert this?  */
 		}
@@ -1610,28 +1610,28 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
 	if (mdev->tconn->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->tconn->req_lock);
-		D_ASSERT(!drbd_interval_empty(&e->i));
-		drbd_remove_epoch_entry_interval(mdev, e);
+		D_ASSERT(!drbd_interval_empty(&peer_req->i));
+		drbd_remove_epoch_entry_interval(mdev, peer_req);
 		spin_unlock_irq(&mdev->tconn->req_lock);
 	} else
-		D_ASSERT(drbd_interval_empty(&e->i));
+		D_ASSERT(drbd_interval_empty(&peer_req->i));
 
-	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
+	drbd_may_finish_epoch(mdev, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
 
 	return ok;
 }
 
 static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
-	struct drbd_peer_request *e = (struct drbd_peer_request *)w;
+	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
 	int ok = 1;
 
 	D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
-	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
+	ok = drbd_send_ack(mdev, P_DISCARD_ACK, peer_req);
 
 	spin_lock_irq(&mdev->tconn->req_lock);
-	D_ASSERT(!drbd_interval_empty(&e->i));
-	drbd_remove_epoch_entry_interval(mdev, e);
+	D_ASSERT(!drbd_interval_empty(&peer_req->i));
+	drbd_remove_epoch_entry_interval(mdev, peer_req);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	dec_unacked(mdev);
@@ -1735,7 +1735,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 			unsigned int data_size)
 {
 	sector_t sector;
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 	struct p_data *p = &mdev->tconn->data.rbuf.data;
 	int rw = WRITE;
 	u32 dp_flags;
@@ -1757,24 +1757,24 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 	 * the end of this function. */
 
 	sector = be64_to_cpu(p->sector);
-	e = read_in_block(mdev, p->block_id, sector, data_size);
-	if (!e) {
+	peer_req = read_in_block(mdev, p->block_id, sector, data_size);
+	if (!peer_req) {
 		put_ldev(mdev);
 		return false;
 	}
 
-	e->w.cb = e_end_block;
+	peer_req->w.cb = e_end_block;
 
 	dp_flags = be32_to_cpu(p->dp_flags);
 	rw |= wire_flags_to_bio(mdev, dp_flags);
 
 	if (dp_flags & DP_MAY_SET_IN_SYNC)
-		e->flags |= EE_MAY_SET_IN_SYNC;
+		peer_req->flags |= EE_MAY_SET_IN_SYNC;
 
 	spin_lock(&mdev->epoch_lock);
-	e->epoch = mdev->current_epoch;
-	atomic_inc(&e->epoch->epoch_size);
-	atomic_inc(&e->epoch->active);
+	peer_req->epoch = mdev->current_epoch;
+	atomic_inc(&peer_req->epoch->epoch_size);
+	atomic_inc(&peer_req->epoch->active);
 	spin_unlock(&mdev->epoch_lock);
 
 	/* I'm the receiver, I do hold a net_cnt reference. */
@@ -1783,7 +1783,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 	} else {
 		/* don't get the req_lock yet,
 		 * we may sleep in drbd_wait_peer_seq */
-		const int size = e->i.size;
+		const int size = peer_req->i.size;
 		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags);
 		DEFINE_WAIT(wait);
 		int first;
@@ -1860,8 +1860,8 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 				dev_alert(DEV, "Concurrent write! [DISCARD BY FLAG] sec=%llus\n",
 				     (unsigned long long)sector);
 				inc_unacked(mdev);
-				e->w.cb = e_send_discard_ack;
-				list_add_tail(&e->w.list, &mdev->done_ee);
+				peer_req->w.cb = e_send_discard_ack;
+				list_add_tail(&peer_req->w.list, &mdev->done_ee);
 
 				spin_unlock_irq(&mdev->tconn->req_lock);
 
@@ -1898,10 +1898,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 		}
 		finish_wait(&mdev->misc_wait, &wait);
 
-		drbd_insert_interval(&mdev->write_requests, &e->i);
+		drbd_insert_interval(&mdev->write_requests, &peer_req->i);
 	}
 
-	list_add(&e->w.list, &mdev->active_ee);
+	list_add(&peer_req->w.list, &mdev->active_ee);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	switch (mdev->tconn->net_conf->wire_protocol) {
@@ -1913,7 +1913,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 	case DRBD_PROT_B:
 		/* I really don't like it that the receiver thread
 		 * sends on the msock, but anyways */
-		drbd_send_ack(mdev, P_RECV_ACK, e);
+		drbd_send_ack(mdev, P_RECV_ACK, peer_req);
 		break;
 	case DRBD_PROT_A:
 		/* nothing to do */
@@ -1922,28 +1922,28 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 
 	if (mdev->state.pdsk < D_INCONSISTENT) {
 		/* In case we have the only disk of the cluster, */
-		drbd_set_out_of_sync(mdev, e->i.sector, e->i.size);
-		e->flags |= EE_CALL_AL_COMPLETE_IO;
-		e->flags &= ~EE_MAY_SET_IN_SYNC;
-		drbd_al_begin_io(mdev, e->i.sector);
+		drbd_set_out_of_sync(mdev, peer_req->i.sector, peer_req->i.size);
+		peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
+		peer_req->flags &= ~EE_MAY_SET_IN_SYNC;
+		drbd_al_begin_io(mdev, peer_req->i.sector);
 	}
 
-	if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0)
+	if (drbd_submit_ee(mdev, peer_req, rw, DRBD_FAULT_DT_WR) == 0)
 		return true;
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_del(&e->w.list);
-	drbd_remove_epoch_entry_interval(mdev, e);
+	list_del(&peer_req->w.list);
+	drbd_remove_epoch_entry_interval(mdev, peer_req);
 	spin_unlock_irq(&mdev->tconn->req_lock);
-	if (e->flags & EE_CALL_AL_COMPLETE_IO)
-		drbd_al_complete_io(mdev, e->i.sector);
+	if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
+		drbd_al_complete_io(mdev, peer_req->i.sector);
 
 out_interrupted:
-	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + EV_CLEANUP);
+	drbd_may_finish_epoch(mdev, peer_req->epoch, EV_PUT + EV_CLEANUP);
 	put_ldev(mdev);
-	drbd_free_ee(mdev, e);
+	drbd_free_ee(mdev, peer_req);
 	return false;
 }
 
@@ -2019,7 +2019,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 {
 	sector_t sector;
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 	struct digest_info *di = NULL;
 	int size, verb;
 	unsigned int fault_type;
@@ -2070,21 +2070,21 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 	/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
 	 * "criss-cross" setup, that might cause write-out on some other DRBD,
 	 * which in turn might block on the other node at this very place.  */
-	e = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO);
-	if (!e) {
+	peer_req = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO);
+	if (!peer_req) {
 		put_ldev(mdev);
 		return false;
 	}
 
 	switch (cmd) {
 	case P_DATA_REQUEST:
-		e->w.cb = w_e_end_data_req;
+		peer_req->w.cb = w_e_end_data_req;
 		fault_type = DRBD_FAULT_DT_RD;
 		/* application IO, don't drbd_rs_begin_io */
 		goto submit;
 
 	case P_RS_DATA_REQUEST:
-		e->w.cb = w_e_end_rsdata_req;
+		peer_req->w.cb = w_e_end_rsdata_req;
 		fault_type = DRBD_FAULT_RS_RD;
 		/* used in the sector offset progress display */
 		mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
@@ -2100,21 +2100,21 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 		di->digest_size = digest_size;
 		di->digest = (((char *)di)+sizeof(struct digest_info));
 
-		e->digest = di;
-		e->flags |= EE_HAS_DIGEST;
+		peer_req->digest = di;
+		peer_req->flags |= EE_HAS_DIGEST;
 
 		if (drbd_recv(mdev, di->digest, digest_size) != digest_size)
 			goto out_free_e;
 
 		if (cmd == P_CSUM_RS_REQUEST) {
 			D_ASSERT(mdev->tconn->agreed_pro_version >= 89);
-			e->w.cb = w_e_end_csum_rs_req;
+			peer_req->w.cb = w_e_end_csum_rs_req;
 			/* used in the sector offset progress display */
 			mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
 		} else if (cmd == P_OV_REPLY) {
 			/* track progress, we may need to throttle */
 			atomic_add(size >> 9, &mdev->rs_sect_in);
-			e->w.cb = w_e_end_ov_reply;
+			peer_req->w.cb = w_e_end_ov_reply;
 			dec_rs_pending(mdev);
 			/* drbd_rs_begin_io done when we sent this request,
 			 * but accounting still needs to be done. */
@@ -2138,7 +2138,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 			dev_info(DEV, "Online Verify start sector: %llu\n",
 					(unsigned long long)sector);
 		}
-		e->w.cb = w_e_end_ov_req;
+		peer_req->w.cb = w_e_end_ov_req;
 		fault_type = DRBD_FAULT_RS_RD;
 		break;
 
@@ -2182,22 +2182,22 @@ submit_for_resync:
 submit:
 	inc_unacked(mdev);
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_add_tail(&e->w.list, &mdev->read_ee);
+	list_add_tail(&peer_req->w.list, &mdev->read_ee);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
+	if (drbd_submit_ee(mdev, peer_req, READ, fault_type) == 0)
 		return true;
 
 	/* don't care for the reason here */
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_del(&e->w.list);
+	list_del(&peer_req->w.list);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 	/* no drbd_rs_complete_io(), we are dropping the connection anyways */
 
 out_free_e:
 	put_ldev(mdev);
-	drbd_free_ee(mdev, e);
+	drbd_free_ee(mdev, peer_req);
 	return false;
 }
 
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 06628d1..f13d56c 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -80,47 +80,47 @@ void drbd_md_io_complete(struct bio *bio, int error)
 /* reads on behalf of the partner,
  * "submitted" by the receiver
  */
-void drbd_endio_read_sec_final(struct drbd_peer_request *e) __releases(local)
+void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
 {
 	unsigned long flags = 0;
-	struct drbd_conf *mdev = e->mdev;
+	struct drbd_conf *mdev = peer_req->mdev;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	mdev->read_cnt += e->i.size >> 9;
-	list_del(&e->w.list);
+	mdev->read_cnt += peer_req->i.size >> 9;
+	list_del(&peer_req->w.list);
 	if (list_empty(&mdev->read_ee))
 		wake_up(&mdev->ee_wait);
-	if (test_bit(__EE_WAS_ERROR, &e->flags))
+	if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
 		__drbd_chk_io_error(mdev, false);
 	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
-	drbd_queue_work(&mdev->tconn->data.work, &e->w);
+	drbd_queue_work(&mdev->tconn->data.work, &peer_req->w);
 	put_ldev(mdev);
 }
 
 /* writes on behalf of the partner, or resync writes,
  * "submitted" by the receiver, final stage.  */
-static void drbd_endio_write_sec_final(struct drbd_peer_request *e) __releases(local)
+static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
 {
 	unsigned long flags = 0;
-	struct drbd_conf *mdev = e->mdev;
+	struct drbd_conf *mdev = peer_req->mdev;
 	sector_t e_sector;
 	int do_wake;
 	u64 block_id;
 	int do_al_complete_io;
 
-	/* after we moved e to done_ee,
+	/* after we moved peer_req to done_ee,
 	 * we may no longer access it,
 	 * it may be freed/reused already!
 	 * (as soon as we release the req_lock) */
-	e_sector = e->i.sector;
-	do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
-	block_id = e->block_id;
+	e_sector = peer_req->i.sector;
+	do_al_complete_io = peer_req->flags & EE_CALL_AL_COMPLETE_IO;
+	block_id = peer_req->block_id;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	mdev->writ_cnt += e->i.size >> 9;
-	list_del(&e->w.list); /* has been on active_ee or sync_ee */
-	list_add_tail(&e->w.list, &mdev->done_ee);
+	mdev->writ_cnt += peer_req->i.size >> 9;
+	list_del(&peer_req->w.list); /* has been on active_ee or sync_ee */
+	list_add_tail(&peer_req->w.list, &mdev->done_ee);
 
 	/*
 	 * Do not remove from the write_requests tree here: we did not send the
@@ -132,7 +132,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *e) __releases(l
 
 	do_wake = list_empty(block_id == ID_SYNCER ? &mdev->sync_ee : &mdev->active_ee);
 
-	if (test_bit(__EE_WAS_ERROR, &e->flags))
+	if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
 		__drbd_chk_io_error(mdev, false);
 	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
@@ -154,20 +154,20 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *e) __releases(l
  */
 void drbd_endio_sec(struct bio *bio, int error)
 {
-	struct drbd_peer_request *e = bio->bi_private;
-	struct drbd_conf *mdev = e->mdev;
+	struct drbd_peer_request *peer_req = bio->bi_private;
+	struct drbd_conf *mdev = peer_req->mdev;
 	int uptodate = bio_flagged(bio, BIO_UPTODATE);
 	int is_write = bio_data_dir(bio) == WRITE;
 
 	if (error && __ratelimit(&drbd_ratelimit_state))
 		dev_warn(DEV, "%s: error=%d s=%llus\n",
 				is_write ? "write" : "read", error,
-				(unsigned long long)e->i.sector);
+				(unsigned long long)peer_req->i.sector);
 	if (!error && !uptodate) {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_warn(DEV, "%s: setting error to -EIO s=%llus\n",
 					is_write ? "write" : "read",
-					(unsigned long long)e->i.sector);
+					(unsigned long long)peer_req->i.sector);
 		/* strange behavior of some lower level drivers...
 		 * fail the request by clearing the uptodate flag,
 		 * but do not return any error?! */
@@ -175,14 +175,14 @@ void drbd_endio_sec(struct bio *bio, int error)
 	}
 
 	if (error)
-		set_bit(__EE_WAS_ERROR, &e->flags);
+		set_bit(__EE_WAS_ERROR, &peer_req->flags);
 
 	bio_put(bio); /* no need for the bio anymore */
-	if (atomic_dec_and_test(&e->pending_bios)) {
+	if (atomic_dec_and_test(&peer_req->pending_bios)) {
 		if (is_write)
-			drbd_endio_write_sec_final(e);
+			drbd_endio_write_sec_final(peer_req);
 		else
-			drbd_endio_read_sec_final(e);
+			drbd_endio_read_sec_final(peer_req);
 	}
 }
 
@@ -248,11 +248,11 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 }
 
 void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm,
-		  struct drbd_peer_request *e, void *digest)
+		  struct drbd_peer_request *peer_req, void *digest)
 {
 	struct hash_desc desc;
 	struct scatterlist sg;
-	struct page *page = e->pages;
+	struct page *page = peer_req->pages;
 	struct page *tmp;
 	unsigned len;
 
@@ -269,7 +269,7 @@ void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm,
 		page = tmp;
 	}
 	/* and now the last, possibly only partially used page */
-	len = e->i.size & (PAGE_SIZE - 1);
+	len = peer_req->i.size & (PAGE_SIZE - 1);
 	sg_set_page(&sg, page, len ?: PAGE_SIZE, 0);
 	crypto_hash_update(&desc, &sg, sg.length);
 	crypto_hash_final(&desc, digest);
@@ -298,7 +298,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
 /* TODO merge common code with w_e_end_ov_req */
 int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req =
+		container_of(w, struct drbd_peer_request, w);
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -306,22 +307,22 @@ int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	if (unlikely(cancel))
 		goto out;
 
-	if (likely((e->flags & EE_WAS_ERROR) != 0))
+	if (likely((peer_req->flags & EE_WAS_ERROR) != 0))
 		goto out;
 
 	digest_size = crypto_hash_digestsize(mdev->csums_tfm);
 	digest = kmalloc(digest_size, GFP_NOIO);
 	if (digest) {
-		sector_t sector = e->i.sector;
-		unsigned int size = e->i.size;
-		drbd_csum_ee(mdev, mdev->csums_tfm, e, digest);
+		sector_t sector = peer_req->i.sector;
+		unsigned int size = peer_req->i.size;
+		drbd_csum_ee(mdev, mdev->csums_tfm, peer_req, digest);
 		/* Free e and pages before send.
 		 * In case we block on congestion, we could otherwise run into
 		 * some distributed deadlock, if the other side blocks on
 		 * congestion as well, because our receiver blocks in
 		 * drbd_pp_alloc due to pp_in_use > max_buffers. */
-		drbd_free_ee(mdev, e);
-		e = NULL;
+		drbd_free_ee(mdev, peer_req);
+		peer_req = NULL;
 		inc_rs_pending(mdev);
 		ok = drbd_send_drequest_csum(mdev, sector, size,
 					     digest, digest_size,
@@ -333,8 +334,8 @@ int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	}
 
 out:
-	if (e)
-		drbd_free_ee(mdev, e);
+	if (peer_req)
+		drbd_free_ee(mdev, peer_req);
 
 	if (unlikely(!ok))
 		dev_err(DEV, "drbd_send_drequest(..., csum) failed\n");
@@ -345,7 +346,7 @@ out:
 
 static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 {
-	struct drbd_peer_request *e;
+	struct drbd_peer_request *peer_req;
 
 	if (!get_ldev(mdev))
 		return -EIO;
@@ -355,17 +356,17 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 
 	/* GFP_TRY, because if there is no memory available right now, this may
 	 * be rescheduled for later. It is "only" background resync, after all. */
-	e = drbd_alloc_ee(mdev, ID_SYNCER /* unused */, sector, size, GFP_TRY);
-	if (!e)
+	peer_req = drbd_alloc_ee(mdev, ID_SYNCER /* unused */, sector, size, GFP_TRY);
+	if (!peer_req)
 		goto defer;
 
-	e->w.cb = w_e_send_csum;
+	peer_req->w.cb = w_e_send_csum;
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_add(&e->w.list, &mdev->read_ee);
+	list_add(&peer_req->w.list, &mdev->read_ee);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	atomic_add(size >> 9, &mdev->rs_sect_ev);
-	if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
+	if (drbd_submit_ee(mdev, peer_req, READ, DRBD_FAULT_RS_RD) == 0)
 		return 0;
 
 	/* If it failed because of ENOMEM, retry should help.  If it failed
@@ -373,10 +374,10 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
 	 * retry may or may not help.
 	 * If it does not, you may need to force disconnect. */
 	spin_lock_irq(&mdev->tconn->req_lock);
-	list_del(&e->w.list);
+	list_del(&peer_req->w.list);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	drbd_free_ee(mdev, e);
+	drbd_free_ee(mdev, peer_req);
 defer:
 	put_ldev(mdev);
 	return -EAGAIN;
@@ -901,19 +902,19 @@ out:
 }
 
 /* helper */
-static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_peer_request *e)
+static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_peer_request *peer_req)
 {
-	if (drbd_ee_has_active_page(e)) {
+	if (drbd_ee_has_active_page(peer_req)) {
 		/* This might happen if sendpage() has not finished */
-		int i = (e->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
+		int i = (peer_req->i.size + PAGE_SIZE -1) >> PAGE_SHIFT;
 		atomic_add(i, &mdev->pp_in_use_by_net);
 		atomic_sub(i, &mdev->pp_in_use);
 		spin_lock_irq(&mdev->tconn->req_lock);
-		list_add_tail(&e->w.list, &mdev->net_ee);
+		list_add_tail(&peer_req->w.list, &mdev->net_ee);
 		spin_unlock_irq(&mdev->tconn->req_lock);
 		wake_up(&drbd_pp_wait);
 	} else
-		drbd_free_ee(mdev, e);
+		drbd_free_ee(mdev, peer_req);
 }
 
 /**
@@ -924,28 +925,28 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_peer_requ
  */
 int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
 	int ok;
 
 	if (unlikely(cancel)) {
-		drbd_free_ee(mdev, e);
+		drbd_free_ee(mdev, peer_req);
 		dec_unacked(mdev);
 		return 1;
 	}
 
-	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
-		ok = drbd_send_block(mdev, P_DATA_REPLY, e);
+	if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
+		ok = drbd_send_block(mdev, P_DATA_REPLY, peer_req);
 	} else {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "Sending NegDReply. sector=%llus.\n",
-			    (unsigned long long)e->i.sector);
+			    (unsigned long long)peer_req->i.sector);
 
-		ok = drbd_send_ack(mdev, P_NEG_DREPLY, e);
+		ok = drbd_send_ack(mdev, P_NEG_DREPLY, peer_req);
 	}
 
 	dec_unacked(mdev);
 
-	move_to_net_ee_or_free(mdev, e);
+	move_to_net_ee_or_free(mdev, peer_req);
 
 	if (unlikely(!ok))
 		dev_err(DEV, "drbd_send_block() failed\n");
@@ -960,26 +961,26 @@ int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
  */
 int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
 	int ok;
 
 	if (unlikely(cancel)) {
-		drbd_free_ee(mdev, e);
+		drbd_free_ee(mdev, peer_req);
 		dec_unacked(mdev);
 		return 1;
 	}
 
 	if (get_ldev_if_state(mdev, D_FAILED)) {
-		drbd_rs_complete_io(mdev, e->i.sector);
+		drbd_rs_complete_io(mdev, peer_req->i.sector);
 		put_ldev(mdev);
 	}
 
 	if (mdev->state.conn == C_AHEAD) {
-		ok = drbd_send_ack(mdev, P_RS_CANCEL, e);
-	} else if (likely((e->flags & EE_WAS_ERROR) == 0)) {
+		ok = drbd_send_ack(mdev, P_RS_CANCEL, peer_req);
+	} else if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
 		if (likely(mdev->state.pdsk >= D_INCONSISTENT)) {
 			inc_rs_pending(mdev);
-			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e);
+			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, peer_req);
 		} else {
 			if (__ratelimit(&drbd_ratelimit_state))
 				dev_err(DEV, "Not sending RSDataReply, "
@@ -989,17 +990,17 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	} else {
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "Sending NegRSDReply. sector %llus.\n",
-			    (unsigned long long)e->i.sector);
+			    (unsigned long long)peer_req->i.sector);
 
-		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
+		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, peer_req);
 
 		/* update resync data with failure */
-		drbd_rs_failed_io(mdev, e->i.sector, e->i.size);
+		drbd_rs_failed_io(mdev, peer_req->i.sector, peer_req->i.size);
 	}
 
 	dec_unacked(mdev);
 
-	move_to_net_ee_or_free(mdev, e);
+	move_to_net_ee_or_free(mdev, peer_req);
 
 	if (unlikely(!ok))
 		dev_err(DEV, "drbd_send_block() failed\n");
@@ -1008,26 +1009,26 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
 int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
 	struct digest_info *di;
 	int digest_size;
 	void *digest = NULL;
 	int ok, eq = 0;
 
 	if (unlikely(cancel)) {
-		drbd_free_ee(mdev, e);
+		drbd_free_ee(mdev, peer_req);
 		dec_unacked(mdev);
 		return 1;
 	}
 
 	if (get_ldev(mdev)) {
-		drbd_rs_complete_io(mdev, e->i.sector);
+		drbd_rs_complete_io(mdev, peer_req->i.sector);
 		put_ldev(mdev);
 	}
 
-	di = e->digest;
+	di = peer_req->digest;
 
-	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
+	if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
 		/* quick hack to try to avoid a race against reconfiguration.
 		 * a real fix would be much more involved,
 		 * introducing more locking mechanisms */
@@ -1037,31 +1038,31 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 			digest = kmalloc(digest_size, GFP_NOIO);
 		}
 		if (digest) {
-			drbd_csum_ee(mdev, mdev->csums_tfm, e, digest);
+			drbd_csum_ee(mdev, mdev->csums_tfm, peer_req, digest);
 			eq = !memcmp(digest, di->digest, digest_size);
 			kfree(digest);
 		}
 
 		if (eq) {
-			drbd_set_in_sync(mdev, e->i.sector, e->i.size);
+			drbd_set_in_sync(mdev, peer_req->i.sector, peer_req->i.size);
 			/* rs_same_csums unit is BM_BLOCK_SIZE */
-			mdev->rs_same_csum += e->i.size >> BM_BLOCK_SHIFT;
-			ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
+			mdev->rs_same_csum += peer_req->i.size >> BM_BLOCK_SHIFT;
+			ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, peer_req);
 		} else {
 			inc_rs_pending(mdev);
-			e->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
-			e->flags &= ~EE_HAS_DIGEST; /* This e no longer has a digest pointer */
+			peer_req->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
+			peer_req->flags &= ~EE_HAS_DIGEST; /* This peer request no longer has a digest pointer */
 			kfree(di);
-			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e);
+			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, peer_req);
 		}
 	} else {
-		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
+		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, peer_req);
 		if (__ratelimit(&drbd_ratelimit_state))
 			dev_err(DEV, "Sending NegDReply. I guess it gets messy.\n");
 	}
 
 	dec_unacked(mdev);
-	move_to_net_ee_or_free(mdev, e);
+	move_to_net_ee_or_free(mdev, peer_req);
 
 	if (unlikely(!ok))
 		dev_err(DEV, "drbd_send_block/ack() failed\n");
@@ -1071,9 +1072,9 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 /* TODO merge common code with w_e_send_csum */
 int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
-	sector_t sector = e->i.sector;
-	unsigned int size = e->i.size;
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	sector_t sector = peer_req->i.sector;
+	unsigned int size = peer_req->i.size;
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -1088,8 +1089,8 @@ int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		goto out;
 	}
 
-	if (likely(!(e->flags & EE_WAS_ERROR)))
-		drbd_csum_ee(mdev, mdev->verify_tfm, e, digest);
+	if (likely(!(peer_req->flags & EE_WAS_ERROR)))
+		drbd_csum_ee(mdev, mdev->verify_tfm, peer_req, digest);
 	else
 		memset(digest, 0, digest_size);
 
@@ -1098,8 +1099,8 @@ int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * some distributed deadlock, if the other side blocks on
 	 * congestion as well, because our receiver blocks in
 	 * drbd_pp_alloc due to pp_in_use > max_buffers. */
-	drbd_free_ee(mdev, e);
-	e = NULL;
+	drbd_free_ee(mdev, peer_req);
+	peer_req = NULL;
 	inc_rs_pending(mdev);
 	ok = drbd_send_drequest_csum(mdev, sector, size,
 				     digest, digest_size,
@@ -1109,8 +1110,8 @@ int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	kfree(digest);
 
 out:
-	if (e)
-		drbd_free_ee(mdev, e);
+	if (peer_req)
+		drbd_free_ee(mdev, peer_req);
 	dec_unacked(mdev);
 	return ok;
 }
@@ -1128,16 +1129,16 @@ void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size)
 
 int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *e = container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
 	struct digest_info *di;
 	void *digest;
-	sector_t sector = e->i.sector;
-	unsigned int size = e->i.size;
+	sector_t sector = peer_req->i.sector;
+	unsigned int size = peer_req->i.size;
 	int digest_size;
 	int ok, eq = 0;
 
 	if (unlikely(cancel)) {
-		drbd_free_ee(mdev, e);
+		drbd_free_ee(mdev, peer_req);
 		dec_unacked(mdev);
 		return 1;
 	}
@@ -1145,17 +1146,17 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	/* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all
 	 * the resync lru has been cleaned up already */
 	if (get_ldev(mdev)) {
-		drbd_rs_complete_io(mdev, e->i.sector);
+		drbd_rs_complete_io(mdev, peer_req->i.sector);
 		put_ldev(mdev);
 	}
 
-	di = e->digest;
+	di = peer_req->digest;
 
-	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
+	if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) {
 		digest_size = crypto_hash_digestsize(mdev->verify_tfm);
 		digest = kmalloc(digest_size, GFP_NOIO);
 		if (digest) {
-			drbd_csum_ee(mdev, mdev->verify_tfm, e, digest);
+			drbd_csum_ee(mdev, mdev->verify_tfm, peer_req, digest);
 
 			D_ASSERT(digest_size == di->digest_size);
 			eq = !memcmp(digest, di->digest, digest_size);
@@ -1168,7 +1169,7 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 		 * some distributed deadlock, if the other side blocks on
 		 * congestion as well, because our receiver blocks in
 		 * drbd_pp_alloc due to pp_in_use > max_buffers. */
-	drbd_free_ee(mdev, e);
+	drbd_free_ee(mdev, peer_req);
 	if (!eq)
 		drbd_ov_oos_found(mdev, sector, size);
 	else
-- 
1.7.4.1


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

* [PATCH 061/118] drbd: Moved the state functions into its own source file
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (59 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 060/118] drbd: Local variable renames: e -> peer_req Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 062/118] drbd: Moved the thread name into the data structure Philipp Reisner
                   ` (58 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/Makefile     |    2 +-
 drivers/block/drbd/drbd_int.h   |   46 +--
 drivers/block/drbd/drbd_main.c  | 1179 +-------------------------------------
 drivers/block/drbd/drbd_state.c | 1217 +++++++++++++++++++++++++++++++++++++++
 drivers/block/drbd/drbd_state.h |  101 ++++
 5 files changed, 1326 insertions(+), 1219 deletions(-)
 create mode 100644 drivers/block/drbd/drbd_state.c
 create mode 100644 drivers/block/drbd/drbd_state.h

diff --git a/drivers/block/drbd/Makefile b/drivers/block/drbd/Makefile
index cacbb04..06fb445 100644
--- a/drivers/block/drbd/Makefile
+++ b/drivers/block/drbd/Makefile
@@ -1,6 +1,6 @@
 drbd-y := drbd_bitmap.o drbd_proc.o
 drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
 drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
-drbd-y += drbd_interval.o
+drbd-y += drbd_interval.o drbd_state.o
 
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd.o
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index f934aa2..2c18cf3 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -43,6 +43,8 @@
 #include <net/tcp.h>
 #include <linux/lru_cache.h>
 #include <linux/prefetch.h>
+#include <linux/drbd.h>
+#include "drbd_state.h"
 
 #ifdef __CHECKER__
 # define __protected_by(x)       __attribute__((require_context(x,1,999,"rdwr")))
@@ -1120,35 +1122,12 @@ static inline void drbd_put_data_sock(struct drbd_conf *mdev)
 
 /* drbd_main.c */
 
-enum chg_state_flags {
-	CS_HARD	= 1,
-	CS_VERBOSE = 2,
-	CS_WAIT_COMPLETE = 4,
-	CS_SERIALIZE    = 8,
-	CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
-};
-
 enum dds_flags {
 	DDSF_FORCED    = 1,
 	DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */
 };
 
 extern void drbd_init_set_defaults(struct drbd_conf *mdev);
-extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
-					    enum chg_state_flags f,
-					    union drbd_state mask,
-					    union drbd_state val);
-extern void drbd_force_state(struct drbd_conf *, union drbd_state,
-			union drbd_state);
-extern enum drbd_state_rv _drbd_request_state(struct drbd_conf *,
-					      union drbd_state,
-					      union drbd_state,
-					      enum chg_state_flags);
-extern enum drbd_state_rv __drbd_set_state(struct drbd_conf *, union drbd_state,
-					   enum chg_state_flags,
-					   struct completion *done);
-extern void print_st_err(struct drbd_conf *, union drbd_state,
-			union drbd_state, int);
 extern int  drbd_thread_start(struct drbd_thread *thi);
 extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
 #ifdef CONFIG_SMP
@@ -1712,6 +1691,10 @@ static inline int drbd_ee_has_active_page(struct drbd_peer_request *peer_req)
 }
 
 
+
+
+
+
 static inline void drbd_state_lock(struct drbd_conf *mdev)
 {
 	wait_event(mdev->misc_wait,
@@ -1737,23 +1720,6 @@ _drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	return rv;
 }
 
-/**
- * drbd_request_state() - Reqest a state change
- * @mdev:	DRBD device.
- * @mask:	mask of state bits to change.
- * @val:	value of new state bits.
- *
- * This is the most graceful way of requesting a state change. It is verbose
- * quite verbose in case the state change is not possible, and all those
- * state changes are globally serialized.
- */
-static inline int drbd_request_state(struct drbd_conf *mdev,
-				     union drbd_state mask,
-				     union drbd_state val)
-{
-	return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED);
-}
-
 #define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
 static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, const char *where)
 {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 44be1f2..ccd57a9 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -56,14 +56,6 @@
 
 #include "drbd_vli.h"
 
-struct after_state_chg_work {
-	struct drbd_work w;
-	union drbd_state os;
-	union drbd_state ns;
-	enum chg_state_flags flags;
-	struct completion *done;
-};
-
 static DEFINE_MUTEX(drbd_main_mutex);
 int drbdd_init(struct drbd_thread *);
 int drbd_worker(struct drbd_thread *);
@@ -72,9 +64,6 @@ int drbd_asender(struct drbd_thread *);
 int drbd_init(void);
 static int drbd_open(struct block_device *bdev, fmode_t mode);
 static int drbd_release(struct gendisk *gd, fmode_t mode);
-static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused);
-static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
-			   union drbd_state ns, enum chg_state_flags flags);
 static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);
 static void md_sync_timer_fn(unsigned long data);
 static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);
@@ -340,7 +329,7 @@ bail:
  * @what might be one of CONNECTION_LOST_WHILE_PENDING, RESEND, FAIL_FROZEN_DISK_IO,
  * RESTART_FROZEN_DISK_IO.
  */
-static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
+void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 {
 	struct drbd_tl_epoch *b, *tmp, **pn;
 	struct list_head *le, *tle, carry_reads;
@@ -450,1172 +439,6 @@ void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 	spin_unlock_irq(&mdev->tconn->req_lock);
 }
 
-/**
- * cl_wide_st_chg() - true if the state change is a cluster wide one
- * @mdev:	DRBD device.
- * @os:		old (current) state.
- * @ns:		new (wanted) state.
- */
-static int cl_wide_st_chg(struct drbd_conf *mdev,
-			  union drbd_state os, union drbd_state ns)
-{
-	return (os.conn >= C_CONNECTED && ns.conn >= C_CONNECTED &&
-		 ((os.role != R_PRIMARY && ns.role == R_PRIMARY) ||
-		  (os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
-		  (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S) ||
-		  (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))) ||
-		(os.conn >= C_CONNECTED && ns.conn == C_DISCONNECTING) ||
-		(os.conn == C_CONNECTED && ns.conn == C_VERIFY_S);
-}
-
-enum drbd_state_rv
-drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
-		  union drbd_state mask, union drbd_state val)
-{
-	unsigned long flags;
-	union drbd_state os, ns;
-	enum drbd_state_rv rv;
-
-	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	rv = _drbd_set_state(mdev, ns, f, NULL);
-	ns = mdev->state;
-	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
-
-	return rv;
-}
-
-/**
- * drbd_force_state() - Impose a change which happens outside our control on our state
- * @mdev:	DRBD device.
- * @mask:	mask of state bits to change.
- * @val:	value of new state bits.
- */
-void drbd_force_state(struct drbd_conf *mdev,
-	union drbd_state mask, union drbd_state val)
-{
-	drbd_change_state(mdev, CS_HARD, mask, val);
-}
-
-static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
-static enum drbd_state_rv is_valid_state_transition(struct drbd_conf *,
-						    union drbd_state,
-						    union drbd_state);
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort);
-int drbd_send_state_req(struct drbd_conf *,
-			union drbd_state, union drbd_state);
-
-static enum drbd_state_rv
-_req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
-	     union drbd_state val)
-{
-	union drbd_state os, ns;
-	unsigned long flags;
-	enum drbd_state_rv rv;
-
-	if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags))
-		return SS_CW_SUCCESS;
-
-	if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags))
-		return SS_CW_FAILED_BY_PEER;
-
-	rv = 0;
-	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
-
-	if (!cl_wide_st_chg(mdev, os, ns))
-		rv = SS_CW_NO_NEED;
-	if (!rv) {
-		rv = is_valid_state(mdev, ns);
-		if (rv == SS_SUCCESS) {
-			rv = is_valid_state_transition(mdev, ns, os);
-			if (rv == SS_SUCCESS)
-				rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
-		}
-	}
-	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
-
-	return rv;
-}
-
-/**
- * drbd_req_state() - Perform an eventually cluster wide state change
- * @mdev:	DRBD device.
- * @mask:	mask of state bits to change.
- * @val:	value of new state bits.
- * @f:		flags
- *
- * Should not be called directly, use drbd_request_state() or
- * _drbd_request_state().
- */
-static enum drbd_state_rv
-drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
-	       union drbd_state val, enum chg_state_flags f)
-{
-	struct completion done;
-	unsigned long flags;
-	union drbd_state os, ns;
-	enum drbd_state_rv rv;
-
-	init_completion(&done);
-
-	if (f & CS_SERIALIZE)
-		mutex_lock(&mdev->state_mutex);
-
-	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
-
-	if (cl_wide_st_chg(mdev, os, ns)) {
-		rv = is_valid_state(mdev, ns);
-		if (rv == SS_SUCCESS)
-			rv = is_valid_state_transition(mdev, ns, os);
-		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
-
-		if (rv < SS_SUCCESS) {
-			if (f & CS_VERBOSE)
-				print_st_err(mdev, os, ns, rv);
-			goto abort;
-		}
-
-		drbd_state_lock(mdev);
-		if (!drbd_send_state_req(mdev, mask, val)) {
-			drbd_state_unlock(mdev);
-			rv = SS_CW_FAILED_BY_PEER;
-			if (f & CS_VERBOSE)
-				print_st_err(mdev, os, ns, rv);
-			goto abort;
-		}
-
-		wait_event(mdev->state_wait,
-			(rv = _req_st_cond(mdev, mask, val)));
-
-		if (rv < SS_SUCCESS) {
-			drbd_state_unlock(mdev);
-			if (f & CS_VERBOSE)
-				print_st_err(mdev, os, ns, rv);
-			goto abort;
-		}
-		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-		os = mdev->state;
-		ns.i = (os.i & ~mask.i) | val.i;
-		rv = _drbd_set_state(mdev, ns, f, &done);
-		drbd_state_unlock(mdev);
-	} else {
-		rv = _drbd_set_state(mdev, ns, f, &done);
-	}
-
-	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
-
-	if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
-		D_ASSERT(current != mdev->tconn->worker.task);
-		wait_for_completion(&done);
-	}
-
-abort:
-	if (f & CS_SERIALIZE)
-		mutex_unlock(&mdev->state_mutex);
-
-	return rv;
-}
-
-/**
- * _drbd_request_state() - Request a state change (with flags)
- * @mdev:	DRBD device.
- * @mask:	mask of state bits to change.
- * @val:	value of new state bits.
- * @f:		flags
- *
- * Cousin of drbd_request_state(), useful with the CS_WAIT_COMPLETE
- * flag, or when logging of failed state change requests is not desired.
- */
-enum drbd_state_rv
-_drbd_request_state(struct drbd_conf *mdev, union drbd_state mask,
-		    union drbd_state val, enum chg_state_flags f)
-{
-	enum drbd_state_rv rv;
-
-	wait_event(mdev->state_wait,
-		   (rv = drbd_req_state(mdev, mask, val, f)) != SS_IN_TRANSIENT_STATE);
-
-	return rv;
-}
-
-static void print_st(struct drbd_conf *mdev, char *name, union drbd_state ns)
-{
-	dev_err(DEV, " %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c }\n",
-	    name,
-	    drbd_conn_str(ns.conn),
-	    drbd_role_str(ns.role),
-	    drbd_role_str(ns.peer),
-	    drbd_disk_str(ns.disk),
-	    drbd_disk_str(ns.pdsk),
-	    is_susp(ns) ? 's' : 'r',
-	    ns.aftr_isp ? 'a' : '-',
-	    ns.peer_isp ? 'p' : '-',
-	    ns.user_isp ? 'u' : '-'
-	    );
-}
-
-void print_st_err(struct drbd_conf *mdev, union drbd_state os,
-	          union drbd_state ns, enum drbd_state_rv err)
-{
-	if (err == SS_IN_TRANSIENT_STATE)
-		return;
-	dev_err(DEV, "State change failed: %s\n", drbd_set_st_err_str(err));
-	print_st(mdev, " state", os);
-	print_st(mdev, "wanted", ns);
-}
-
-
-/**
- * is_valid_state() - Returns an SS_ error code if ns is not valid
- * @mdev:	DRBD device.
- * @ns:		State to consider.
- */
-static enum drbd_state_rv
-is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
-{
-	/* See drbd_state_sw_errors in drbd_strings.c */
-
-	enum drbd_fencing_p fp;
-	enum drbd_state_rv rv = SS_SUCCESS;
-
-	fp = FP_DONT_CARE;
-	if (get_ldev(mdev)) {
-		fp = mdev->ldev->dc.fencing;
-		put_ldev(mdev);
-	}
-
-	if (get_net_conf(mdev->tconn)) {
-		if (!mdev->tconn->net_conf->two_primaries &&
-		    ns.role == R_PRIMARY && ns.peer == R_PRIMARY)
-			rv = SS_TWO_PRIMARIES;
-		put_net_conf(mdev->tconn);
-	}
-
-	if (rv <= 0)
-		/* already found a reason to abort */;
-	else if (ns.role == R_SECONDARY && mdev->open_cnt)
-		rv = SS_DEVICE_IN_USE;
-
-	else if (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.disk < D_UP_TO_DATE)
-		rv = SS_NO_UP_TO_DATE_DISK;
-
-	else if (fp >= FP_RESOURCE &&
-		 ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk >= D_UNKNOWN)
-		rv = SS_PRIMARY_NOP;
-
-	else if (ns.role == R_PRIMARY && ns.disk <= D_INCONSISTENT && ns.pdsk <= D_INCONSISTENT)
-		rv = SS_NO_UP_TO_DATE_DISK;
-
-	else if (ns.conn > C_CONNECTED && ns.disk < D_INCONSISTENT)
-		rv = SS_NO_LOCAL_DISK;
-
-	else if (ns.conn > C_CONNECTED && ns.pdsk < D_INCONSISTENT)
-		rv = SS_NO_REMOTE_DISK;
-
-	else if (ns.conn > C_CONNECTED && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE)
-		rv = SS_NO_UP_TO_DATE_DISK;
-
-	else if ((ns.conn == C_CONNECTED ||
-		  ns.conn == C_WF_BITMAP_S ||
-		  ns.conn == C_SYNC_SOURCE ||
-		  ns.conn == C_PAUSED_SYNC_S) &&
-		  ns.disk == D_OUTDATED)
-		rv = SS_CONNECTED_OUTDATES;
-
-	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
-		 (mdev->sync_conf.verify_alg[0] == 0))
-		rv = SS_NO_VERIFY_ALG;
-
-	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
-		  mdev->tconn->agreed_pro_version < 88)
-		rv = SS_NOT_SUPPORTED;
-
-	else if (ns.conn >= C_CONNECTED && ns.pdsk == D_UNKNOWN)
-		rv = SS_CONNECTED_OUTDATES;
-
-	return rv;
-}
-
-/**
- * is_valid_state_transition() - Returns an SS_ error code if the state transition is not possible
- * @mdev:	DRBD device.
- * @ns:		new state.
- * @os:		old state.
- */
-static enum drbd_state_rv
-is_valid_state_transition(struct drbd_conf *mdev, union drbd_state ns,
-			  union drbd_state os)
-{
-	enum drbd_state_rv rv = SS_SUCCESS;
-
-	if ((ns.conn == C_STARTING_SYNC_T || ns.conn == C_STARTING_SYNC_S) &&
-	    os.conn > C_CONNECTED)
-		rv = SS_RESYNC_RUNNING;
-
-	if (ns.conn == C_DISCONNECTING && os.conn == C_STANDALONE)
-		rv = SS_ALREADY_STANDALONE;
-
-	if (ns.disk > D_ATTACHING && os.disk == D_DISKLESS)
-		rv = SS_IS_DISKLESS;
-
-	if (ns.conn == C_WF_CONNECTION && os.conn < C_UNCONNECTED)
-		rv = SS_NO_NET_CONFIG;
-
-	if (ns.disk == D_OUTDATED && os.disk < D_OUTDATED && os.disk != D_ATTACHING)
-		rv = SS_LOWER_THAN_OUTDATED;
-
-	if (ns.conn == C_DISCONNECTING && os.conn == C_UNCONNECTED)
-		rv = SS_IN_TRANSIENT_STATE;
-
-	if (ns.conn == os.conn && ns.conn == C_WF_REPORT_PARAMS)
-		rv = SS_IN_TRANSIENT_STATE;
-
-	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && os.conn < C_CONNECTED)
-		rv = SS_NEED_CONNECTION;
-
-	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
-	    ns.conn != os.conn && os.conn > C_CONNECTED)
-		rv = SS_RESYNC_RUNNING;
-
-	if ((ns.conn == C_STARTING_SYNC_S || ns.conn == C_STARTING_SYNC_T) &&
-	    os.conn < C_CONNECTED)
-		rv = SS_NEED_CONNECTION;
-
-	if ((ns.conn == C_SYNC_TARGET || ns.conn == C_SYNC_SOURCE)
-	    && os.conn < C_WF_REPORT_PARAMS)
-		rv = SS_NEED_CONNECTION; /* No NetworkFailure -> SyncTarget etc... */
-
-	return rv;
-}
-
-/**
- * sanitize_state() - Resolves implicitly necessary additional changes to a state transition
- * @mdev:	DRBD device.
- * @os:		old state.
- * @ns:		new state.
- * @warn_sync_abort:
- *
- * When we loose connection, we have to set the state of the peers disk (pdsk)
- * to D_UNKNOWN. This rule and many more along those lines are in this function.
- */
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort)
-{
-	enum drbd_fencing_p fp;
-	enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max;
-
-	fp = FP_DONT_CARE;
-	if (get_ldev(mdev)) {
-		fp = mdev->ldev->dc.fencing;
-		put_ldev(mdev);
-	}
-
-	/* Disallow Network errors to configure a device's network part */
-	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
-	    os.conn <= C_DISCONNECTING)
-		ns.conn = os.conn;
-
-	/* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow.
-	 * If you try to go into some Sync* state, that shall fail (elsewhere). */
-	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
-	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN)
-		ns.conn = os.conn;
-
-	/* we cannot fail (again) if we already detached */
-	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
-		ns.disk = D_DISKLESS;
-
-	/* if we are only D_ATTACHING yet,
-	 * we can (and should) go directly to D_DISKLESS. */
-	if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
-		ns.disk = D_DISKLESS;
-
-	/* After C_DISCONNECTING only C_STANDALONE may follow */
-	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
-		ns.conn = os.conn;
-
-	if (ns.conn < C_CONNECTED) {
-		ns.peer_isp = 0;
-		ns.peer = R_UNKNOWN;
-		if (ns.pdsk > D_UNKNOWN || ns.pdsk < D_INCONSISTENT)
-			ns.pdsk = D_UNKNOWN;
-	}
-
-	/* Clear the aftr_isp when becoming unconfigured */
-	if (ns.conn == C_STANDALONE && ns.disk == D_DISKLESS && ns.role == R_SECONDARY)
-		ns.aftr_isp = 0;
-
-	/* Abort resync if a disk fails/detaches */
-	if (os.conn > C_CONNECTED && ns.conn > C_CONNECTED &&
-	    (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
-		if (warn_sync_abort)
-			*warn_sync_abort =
-				os.conn == C_VERIFY_S || os.conn == C_VERIFY_T ?
-				"Online-verify" : "Resync";
-		ns.conn = C_CONNECTED;
-	}
-
-	/* Connection breaks down before we finished "Negotiating" */
-	if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING &&
-	    get_ldev_if_state(mdev, D_NEGOTIATING)) {
-		if (mdev->ed_uuid == mdev->ldev->md.uuid[UI_CURRENT]) {
-			ns.disk = mdev->new_state_tmp.disk;
-			ns.pdsk = mdev->new_state_tmp.pdsk;
-		} else {
-			dev_alert(DEV, "Connection lost while negotiating, no data!\n");
-			ns.disk = D_DISKLESS;
-			ns.pdsk = D_UNKNOWN;
-		}
-		put_ldev(mdev);
-	}
-
-	/* D_CONSISTENT and D_OUTDATED vanish when we get connected */
-	if (ns.conn >= C_CONNECTED && ns.conn < C_AHEAD) {
-		if (ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED)
-			ns.disk = D_UP_TO_DATE;
-		if (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED)
-			ns.pdsk = D_UP_TO_DATE;
-	}
-
-	/* Implications of the connection stat on the disk states */
-	disk_min = D_DISKLESS;
-	disk_max = D_UP_TO_DATE;
-	pdsk_min = D_INCONSISTENT;
-	pdsk_max = D_UNKNOWN;
-	switch ((enum drbd_conns)ns.conn) {
-	case C_WF_BITMAP_T:
-	case C_PAUSED_SYNC_T:
-	case C_STARTING_SYNC_T:
-	case C_WF_SYNC_UUID:
-	case C_BEHIND:
-		disk_min = D_INCONSISTENT;
-		disk_max = D_OUTDATED;
-		pdsk_min = D_UP_TO_DATE;
-		pdsk_max = D_UP_TO_DATE;
-		break;
-	case C_VERIFY_S:
-	case C_VERIFY_T:
-		disk_min = D_UP_TO_DATE;
-		disk_max = D_UP_TO_DATE;
-		pdsk_min = D_UP_TO_DATE;
-		pdsk_max = D_UP_TO_DATE;
-		break;
-	case C_CONNECTED:
-		disk_min = D_DISKLESS;
-		disk_max = D_UP_TO_DATE;
-		pdsk_min = D_DISKLESS;
-		pdsk_max = D_UP_TO_DATE;
-		break;
-	case C_WF_BITMAP_S:
-	case C_PAUSED_SYNC_S:
-	case C_STARTING_SYNC_S:
-	case C_AHEAD:
-		disk_min = D_UP_TO_DATE;
-		disk_max = D_UP_TO_DATE;
-		pdsk_min = D_INCONSISTENT;
-		pdsk_max = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/
-		break;
-	case C_SYNC_TARGET:
-		disk_min = D_INCONSISTENT;
-		disk_max = D_INCONSISTENT;
-		pdsk_min = D_UP_TO_DATE;
-		pdsk_max = D_UP_TO_DATE;
-		break;
-	case C_SYNC_SOURCE:
-		disk_min = D_UP_TO_DATE;
-		disk_max = D_UP_TO_DATE;
-		pdsk_min = D_INCONSISTENT;
-		pdsk_max = D_INCONSISTENT;
-		break;
-	case C_STANDALONE:
-	case C_DISCONNECTING:
-	case C_UNCONNECTED:
-	case C_TIMEOUT:
-	case C_BROKEN_PIPE:
-	case C_NETWORK_FAILURE:
-	case C_PROTOCOL_ERROR:
-	case C_TEAR_DOWN:
-	case C_WF_CONNECTION:
-	case C_WF_REPORT_PARAMS:
-	case C_MASK:
-		break;
-	}
-	if (ns.disk > disk_max)
-		ns.disk = disk_max;
-
-	if (ns.disk < disk_min) {
-		dev_warn(DEV, "Implicitly set disk from %s to %s\n",
-			 drbd_disk_str(ns.disk), drbd_disk_str(disk_min));
-		ns.disk = disk_min;
-	}
-	if (ns.pdsk > pdsk_max)
-		ns.pdsk = pdsk_max;
-
-	if (ns.pdsk < pdsk_min) {
-		dev_warn(DEV, "Implicitly set pdsk from %s to %s\n",
-			 drbd_disk_str(ns.pdsk), drbd_disk_str(pdsk_min));
-		ns.pdsk = pdsk_min;
-	}
-
-	if (fp == FP_STONITH &&
-	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
-	    !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
-		ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
-
-	if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
-	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
-	    !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
-		ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
-
-	if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
-		if (ns.conn == C_SYNC_SOURCE)
-			ns.conn = C_PAUSED_SYNC_S;
-		if (ns.conn == C_SYNC_TARGET)
-			ns.conn = C_PAUSED_SYNC_T;
-	} else {
-		if (ns.conn == C_PAUSED_SYNC_S)
-			ns.conn = C_SYNC_SOURCE;
-		if (ns.conn == C_PAUSED_SYNC_T)
-			ns.conn = C_SYNC_TARGET;
-	}
-
-	return ns;
-}
-
-/* helper for __drbd_set_state */
-static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs)
-{
-	if (mdev->tconn->agreed_pro_version < 90)
-		mdev->ov_start_sector = 0;
-	mdev->rs_total = drbd_bm_bits(mdev);
-	mdev->ov_position = 0;
-	if (cs == C_VERIFY_T) {
-		/* starting online verify from an arbitrary position
-		 * does not fit well into the existing protocol.
-		 * on C_VERIFY_T, we initialize ov_left and friends
-		 * implicitly in receive_DataRequest once the
-		 * first P_OV_REQUEST is received */
-		mdev->ov_start_sector = ~(sector_t)0;
-	} else {
-		unsigned long bit = BM_SECT_TO_BIT(mdev->ov_start_sector);
-		if (bit >= mdev->rs_total) {
-			mdev->ov_start_sector =
-				BM_BIT_TO_SECT(mdev->rs_total - 1);
-			mdev->rs_total = 1;
-		} else
-			mdev->rs_total -= bit;
-		mdev->ov_position = mdev->ov_start_sector;
-	}
-	mdev->ov_left = mdev->rs_total;
-}
-
-static void drbd_resume_al(struct drbd_conf *mdev)
-{
-	if (test_and_clear_bit(AL_SUSPENDED, &mdev->flags))
-		dev_info(DEV, "Resumed AL updates\n");
-}
-
-/**
- * __drbd_set_state() - Set a new DRBD state
- * @mdev:	DRBD device.
- * @ns:		new state.
- * @flags:	Flags
- * @done:	Optional completion, that will get completed after the after_state_ch() finished
- *
- * Caller needs to hold req_lock, and global_state_lock. Do not call directly.
- */
-enum drbd_state_rv
-__drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
-	         enum chg_state_flags flags, struct completion *done)
-{
-	union drbd_state os;
-	enum drbd_state_rv rv = SS_SUCCESS;
-	const char *warn_sync_abort = NULL;
-	struct after_state_chg_work *ascw;
-
-	os = mdev->state;
-
-	ns = sanitize_state(mdev, os, ns, &warn_sync_abort);
-
-	if (ns.i == os.i)
-		return SS_NOTHING_TO_DO;
-
-	if (!(flags & CS_HARD)) {
-		/*  pre-state-change checks ; only look at ns  */
-		/* See drbd_state_sw_errors in drbd_strings.c */
-
-		rv = is_valid_state(mdev, ns);
-		if (rv < SS_SUCCESS) {
-			/* If the old state was illegal as well, then let
-			   this happen...*/
-
-			if (is_valid_state(mdev, os) == rv)
-				rv = is_valid_state_transition(mdev, ns, os);
-		} else
-			rv = is_valid_state_transition(mdev, ns, os);
-	}
-
-	if (rv < SS_SUCCESS) {
-		if (flags & CS_VERBOSE)
-			print_st_err(mdev, os, ns, rv);
-		return rv;
-	}
-
-	if (warn_sync_abort)
-		dev_warn(DEV, "%s aborted.\n", warn_sync_abort);
-
-	{
-	char *pbp, pb[300];
-	pbp = pb;
-	*pbp = 0;
-	if (ns.role != os.role)
-		pbp += sprintf(pbp, "role( %s -> %s ) ",
-			       drbd_role_str(os.role),
-			       drbd_role_str(ns.role));
-	if (ns.peer != os.peer)
-		pbp += sprintf(pbp, "peer( %s -> %s ) ",
-			       drbd_role_str(os.peer),
-			       drbd_role_str(ns.peer));
-	if (ns.conn != os.conn)
-		pbp += sprintf(pbp, "conn( %s -> %s ) ",
-			       drbd_conn_str(os.conn),
-			       drbd_conn_str(ns.conn));
-	if (ns.disk != os.disk)
-		pbp += sprintf(pbp, "disk( %s -> %s ) ",
-			       drbd_disk_str(os.disk),
-			       drbd_disk_str(ns.disk));
-	if (ns.pdsk != os.pdsk)
-		pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
-			       drbd_disk_str(os.pdsk),
-			       drbd_disk_str(ns.pdsk));
-	if (is_susp(ns) != is_susp(os))
-		pbp += sprintf(pbp, "susp( %d -> %d ) ",
-			       is_susp(os),
-			       is_susp(ns));
-	if (ns.aftr_isp != os.aftr_isp)
-		pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ",
-			       os.aftr_isp,
-			       ns.aftr_isp);
-	if (ns.peer_isp != os.peer_isp)
-		pbp += sprintf(pbp, "peer_isp( %d -> %d ) ",
-			       os.peer_isp,
-			       ns.peer_isp);
-	if (ns.user_isp != os.user_isp)
-		pbp += sprintf(pbp, "user_isp( %d -> %d ) ",
-			       os.user_isp,
-			       ns.user_isp);
-	dev_info(DEV, "%s\n", pb);
-	}
-
-	/* solve the race between becoming unconfigured,
-	 * worker doing the cleanup, and
-	 * admin reconfiguring us:
-	 * on (re)configure, first set CONFIG_PENDING,
-	 * then wait for a potentially exiting worker,
-	 * start the worker, and schedule one no_op.
-	 * then proceed with configuration.
-	 */
-	if (ns.disk == D_DISKLESS &&
-	    ns.conn == C_STANDALONE &&
-	    ns.role == R_SECONDARY &&
-	    !test_and_set_bit(CONFIG_PENDING, &mdev->flags))
-		set_bit(DEVICE_DYING, &mdev->flags);
-
-	/* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
-	 * on the ldev here, to be sure the transition -> D_DISKLESS resp.
-	 * drbd_ldev_destroy() won't happen before our corresponding
-	 * after_state_ch works run, where we put_ldev again. */
-	if ((os.disk != D_FAILED && ns.disk == D_FAILED) ||
-	    (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
-		atomic_inc(&mdev->local_cnt);
-
-	mdev->state = ns;
-
-	if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)
-		drbd_print_uuids(mdev, "attached to UUIDs");
-
-	wake_up(&mdev->misc_wait);
-	wake_up(&mdev->state_wait);
-
-	/* aborted verify run. log the last position */
-	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
-	    ns.conn < C_CONNECTED) {
-		mdev->ov_start_sector =
-			BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left);
-		dev_info(DEV, "Online Verify reached sector %llu\n",
-			(unsigned long long)mdev->ov_start_sector);
-	}
-
-	if ((os.conn == C_PAUSED_SYNC_T || os.conn == C_PAUSED_SYNC_S) &&
-	    (ns.conn == C_SYNC_TARGET  || ns.conn == C_SYNC_SOURCE)) {
-		dev_info(DEV, "Syncer continues.\n");
-		mdev->rs_paused += (long)jiffies
-				  -(long)mdev->rs_mark_time[mdev->rs_last_mark];
-		if (ns.conn == C_SYNC_TARGET)
-			mod_timer(&mdev->resync_timer, jiffies);
-	}
-
-	if ((os.conn == C_SYNC_TARGET  || os.conn == C_SYNC_SOURCE) &&
-	    (ns.conn == C_PAUSED_SYNC_T || ns.conn == C_PAUSED_SYNC_S)) {
-		dev_info(DEV, "Resync suspended\n");
-		mdev->rs_mark_time[mdev->rs_last_mark] = jiffies;
-	}
-
-	if (os.conn == C_CONNECTED &&
-	    (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T)) {
-		unsigned long now = jiffies;
-		int i;
-
-		set_ov_position(mdev, ns.conn);
-		mdev->rs_start = now;
-		mdev->rs_last_events = 0;
-		mdev->rs_last_sect_ev = 0;
-		mdev->ov_last_oos_size = 0;
-		mdev->ov_last_oos_start = 0;
-
-		for (i = 0; i < DRBD_SYNC_MARKS; i++) {
-			mdev->rs_mark_left[i] = mdev->ov_left;
-			mdev->rs_mark_time[i] = now;
-		}
-
-		drbd_rs_controller_reset(mdev);
-
-		if (ns.conn == C_VERIFY_S) {
-			dev_info(DEV, "Starting Online Verify from sector %llu\n",
-					(unsigned long long)mdev->ov_position);
-			mod_timer(&mdev->resync_timer, jiffies);
-		}
-	}
-
-	if (get_ldev(mdev)) {
-		u32 mdf = mdev->ldev->md.flags & ~(MDF_CONSISTENT|MDF_PRIMARY_IND|
-						 MDF_CONNECTED_IND|MDF_WAS_UP_TO_DATE|
-						 MDF_PEER_OUT_DATED|MDF_CRASHED_PRIMARY);
-
-		if (test_bit(CRASHED_PRIMARY, &mdev->flags))
-			mdf |= MDF_CRASHED_PRIMARY;
-		if (mdev->state.role == R_PRIMARY ||
-		    (mdev->state.pdsk < D_INCONSISTENT && mdev->state.peer == R_PRIMARY))
-			mdf |= MDF_PRIMARY_IND;
-		if (mdev->state.conn > C_WF_REPORT_PARAMS)
-			mdf |= MDF_CONNECTED_IND;
-		if (mdev->state.disk > D_INCONSISTENT)
-			mdf |= MDF_CONSISTENT;
-		if (mdev->state.disk > D_OUTDATED)
-			mdf |= MDF_WAS_UP_TO_DATE;
-		if (mdev->state.pdsk <= D_OUTDATED && mdev->state.pdsk >= D_INCONSISTENT)
-			mdf |= MDF_PEER_OUT_DATED;
-		if (mdf != mdev->ldev->md.flags) {
-			mdev->ldev->md.flags = mdf;
-			drbd_md_mark_dirty(mdev);
-		}
-		if (os.disk < D_CONSISTENT && ns.disk >= D_CONSISTENT)
-			drbd_set_ed_uuid(mdev, mdev->ldev->md.uuid[UI_CURRENT]);
-		put_ldev(mdev);
-	}
-
-	/* Peer was forced D_UP_TO_DATE & R_PRIMARY, consider to resync */
-	if (os.disk == D_INCONSISTENT && os.pdsk == D_INCONSISTENT &&
-	    os.peer == R_SECONDARY && ns.peer == R_PRIMARY)
-		set_bit(CONSIDER_RESYNC, &mdev->flags);
-
-	/* Receiver should clean up itself */
-	if (os.conn != C_DISCONNECTING && ns.conn == C_DISCONNECTING)
-		drbd_thread_stop_nowait(&mdev->tconn->receiver);
-
-	/* Now the receiver finished cleaning up itself, it should die */
-	if (os.conn != C_STANDALONE && ns.conn == C_STANDALONE)
-		drbd_thread_stop_nowait(&mdev->tconn->receiver);
-
-	/* Upon network failure, we need to restart the receiver. */
-	if (os.conn > C_TEAR_DOWN &&
-	    ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
-		drbd_thread_restart_nowait(&mdev->tconn->receiver);
-
-	/* Resume AL writing if we get a connection */
-	if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
-		drbd_resume_al(mdev);
-
-	ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
-	if (ascw) {
-		ascw->os = os;
-		ascw->ns = ns;
-		ascw->flags = flags;
-		ascw->w.cb = w_after_state_ch;
-		ascw->done = done;
-		drbd_queue_work(&mdev->tconn->data.work, &ascw->w);
-	} else {
-		dev_warn(DEV, "Could not kmalloc an ascw\n");
-	}
-
-	return rv;
-}
-
-static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused)
-{
-	struct after_state_chg_work *ascw =
-		container_of(w, struct after_state_chg_work, w);
-	after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags);
-	if (ascw->flags & CS_WAIT_COMPLETE) {
-		D_ASSERT(ascw->done != NULL);
-		complete(ascw->done);
-	}
-	kfree(ascw);
-
-	return 1;
-}
-
-static void abw_start_sync(struct drbd_conf *mdev, int rv)
-{
-	if (rv) {
-		dev_err(DEV, "Writing the bitmap failed not starting resync.\n");
-		_drbd_request_state(mdev, NS(conn, C_CONNECTED), CS_VERBOSE);
-		return;
-	}
-
-	switch (mdev->state.conn) {
-	case C_STARTING_SYNC_T:
-		_drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
-		break;
-	case C_STARTING_SYNC_S:
-		drbd_start_resync(mdev, C_SYNC_SOURCE);
-		break;
-	}
-}
-
-int drbd_bitmap_io_from_worker(struct drbd_conf *mdev,
-		int (*io_fn)(struct drbd_conf *),
-		char *why, enum bm_flag flags)
-{
-	int rv;
-
-	D_ASSERT(current == mdev->tconn->worker.task);
-
-	/* open coded non-blocking drbd_suspend_io(mdev); */
-	set_bit(SUSPEND_IO, &mdev->flags);
-
-	drbd_bm_lock(mdev, why, flags);
-	rv = io_fn(mdev);
-	drbd_bm_unlock(mdev);
-
-	drbd_resume_io(mdev);
-
-	return rv;
-}
-
-/**
- * after_state_ch() - Perform after state change actions that may sleep
- * @mdev:	DRBD device.
- * @os:		old state.
- * @ns:		new state.
- * @flags:	Flags
- */
-static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
-			   union drbd_state ns, enum chg_state_flags flags)
-{
-	enum drbd_fencing_p fp;
-	enum drbd_req_event what = NOTHING;
-	union drbd_state nsm = (union drbd_state){ .i = -1 };
-
-	if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
-		clear_bit(CRASHED_PRIMARY, &mdev->flags);
-		if (mdev->p_uuid)
-			mdev->p_uuid[UI_FLAGS] &= ~((u64)2);
-	}
-
-	fp = FP_DONT_CARE;
-	if (get_ldev(mdev)) {
-		fp = mdev->ldev->dc.fencing;
-		put_ldev(mdev);
-	}
-
-	/* Inform userspace about the change... */
-	drbd_bcast_state(mdev, ns);
-
-	if (!(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE) &&
-	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
-		drbd_khelper(mdev, "pri-on-incon-degr");
-
-	/* Here we have the actions that are performed after a
-	   state change. This function might sleep */
-
-	nsm.i = -1;
-	if (ns.susp_nod) {
-		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
-			what = RESEND;
-
-		if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
-			what = RESTART_FROZEN_DISK_IO;
-
-		if (what != NOTHING)
-			nsm.susp_nod = 0;
-	}
-
-	if (ns.susp_fen) {
-		/* case1: The outdate peer handler is successful: */
-		if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) {
-			tl_clear(mdev);
-			if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
-				drbd_uuid_new_current(mdev);
-				clear_bit(NEW_CUR_UUID, &mdev->flags);
-			}
-			spin_lock_irq(&mdev->tconn->req_lock);
-			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
-			spin_unlock_irq(&mdev->tconn->req_lock);
-		}
-		/* case2: The connection was established again: */
-		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
-			clear_bit(NEW_CUR_UUID, &mdev->flags);
-			what = RESEND;
-			nsm.susp_fen = 0;
-		}
-	}
-
-	if (what != NOTHING) {
-		spin_lock_irq(&mdev->tconn->req_lock);
-		_tl_restart(mdev, what);
-		nsm.i &= mdev->state.i;
-		_drbd_set_state(mdev, nsm, CS_VERBOSE, NULL);
-		spin_unlock_irq(&mdev->tconn->req_lock);
-	}
-
-	/* Became sync source.  With protocol >= 96, we still need to send out
-	 * the sync uuid now. Need to do that before any drbd_send_state, or
-	 * the other side may go "paused sync" before receiving the sync uuids,
-	 * which is unexpected. */
-	if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
-	    (ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
-	    mdev->tconn->agreed_pro_version >= 96 && get_ldev(mdev)) {
-		drbd_gen_and_send_sync_uuid(mdev);
-		put_ldev(mdev);
-	}
-
-	/* Do not change the order of the if above and the two below... */
-	if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) {      /* attach on the peer */
-		drbd_send_uuids(mdev);
-		drbd_send_state(mdev);
-	}
-	/* No point in queuing send_bitmap if we don't have a connection
-	 * anymore, so check also the _current_ state, not only the new state
-	 * at the time this work was queued. */
-	if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S &&
-	    mdev->state.conn == C_WF_BITMAP_S)
-		drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL,
-				"send_bitmap (WFBitMapS)",
-				BM_LOCKED_TEST_ALLOWED);
-
-	/* Lost contact to peer's copy of the data */
-	if ((os.pdsk >= D_INCONSISTENT &&
-	     os.pdsk != D_UNKNOWN &&
-	     os.pdsk != D_OUTDATED)
-	&&  (ns.pdsk < D_INCONSISTENT ||
-	     ns.pdsk == D_UNKNOWN ||
-	     ns.pdsk == D_OUTDATED)) {
-		if (get_ldev(mdev)) {
-			if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
-			    mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
-				if (is_susp(mdev->state)) {
-					set_bit(NEW_CUR_UUID, &mdev->flags);
-				} else {
-					drbd_uuid_new_current(mdev);
-					drbd_send_uuids(mdev);
-				}
-			}
-			put_ldev(mdev);
-		}
-	}
-
-	if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) {
-		if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) {
-			drbd_uuid_new_current(mdev);
-			drbd_send_uuids(mdev);
-		}
-
-		/* D_DISKLESS Peer becomes secondary */
-		if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
-			/* We may still be Primary ourselves.
-			 * No harm done if the bitmap still changes,
-			 * redirtied pages will follow later. */
-			drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
-				"demote diskless peer", BM_LOCKED_SET_ALLOWED);
-		put_ldev(mdev);
-	}
-
-	/* Write out all changed bits on demote.
-	 * Though, no need to da that just yet
-	 * if there is a resync going on still */
-	if (os.role == R_PRIMARY && ns.role == R_SECONDARY &&
-		mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) {
-		/* No changes to the bitmap expected this time, so assert that,
-		 * even though no harm was done if it did change. */
-		drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
-				"demote", BM_LOCKED_TEST_ALLOWED);
-		put_ldev(mdev);
-	}
-
-	/* Last part of the attaching process ... */
-	if (ns.conn >= C_CONNECTED &&
-	    os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) {
-		drbd_send_sizes(mdev, 0, 0);  /* to start sync... */
-		drbd_send_uuids(mdev);
-		drbd_send_state(mdev);
-	}
-
-	/* We want to pause/continue resync, tell peer. */
-	if (ns.conn >= C_CONNECTED &&
-	     ((os.aftr_isp != ns.aftr_isp) ||
-	      (os.user_isp != ns.user_isp)))
-		drbd_send_state(mdev);
-
-	/* In case one of the isp bits got set, suspend other devices. */
-	if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) &&
-	    (ns.aftr_isp || ns.peer_isp || ns.user_isp))
-		suspend_other_sg(mdev);
-
-	/* Make sure the peer gets informed about eventual state
-	   changes (ISP bits) while we were in WFReportParams. */
-	if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
-		drbd_send_state(mdev);
-
-	if (os.conn != C_AHEAD && ns.conn == C_AHEAD)
-		drbd_send_state(mdev);
-
-	/* We are in the progress to start a full sync... */
-	if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
-	    (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S))
-		/* no other bitmap changes expected during this phase */
-		drbd_queue_bitmap_io(mdev,
-			&drbd_bmio_set_n_write, &abw_start_sync,
-			"set_n_write from StartingSync", BM_LOCKED_TEST_ALLOWED);
-
-	/* We are invalidating our self... */
-	if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED &&
-	    os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT)
-		/* other bitmap operation expected during this phase */
-		drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL,
-			"set_n_write from invalidate", BM_LOCKED_MASK);
-
-	/* first half of local IO error, failure to attach,
-	 * or administrative detach */
-	if (os.disk != D_FAILED && ns.disk == D_FAILED) {
-		enum drbd_io_error_p eh;
-		int was_io_error;
-		/* corresponding get_ldev was in __drbd_set_state, to serialize
-		 * our cleanup here with the transition to D_DISKLESS,
-		 * so it is safe to dreference ldev here. */
-		eh = mdev->ldev->dc.on_io_error;
-		was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
-
-		/* current state still has to be D_FAILED,
-		 * there is only one way out: to D_DISKLESS,
-		 * and that may only happen after our put_ldev below. */
-		if (mdev->state.disk != D_FAILED)
-			dev_err(DEV,
-				"ASSERT FAILED: disk is %s during detach\n",
-				drbd_disk_str(mdev->state.disk));
-
-		if (drbd_send_state(mdev))
-			dev_warn(DEV, "Notified peer that I am detaching my disk\n");
-		else
-			dev_err(DEV, "Sending state for detaching disk failed\n");
-
-		drbd_rs_cancel_all(mdev);
-
-		/* In case we want to get something to stable storage still,
-		 * this may be the last chance.
-		 * Following put_ldev may transition to D_DISKLESS. */
-		drbd_md_sync(mdev);
-		put_ldev(mdev);
-
-		if (was_io_error && eh == EP_CALL_HELPER)
-			drbd_khelper(mdev, "local-io-error");
-	}
-
-        /* second half of local IO error, failure to attach,
-         * or administrative detach,
-         * after local_cnt references have reached zero again */
-        if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) {
-                /* We must still be diskless,
-                 * re-attach has to be serialized with this! */
-                if (mdev->state.disk != D_DISKLESS)
-                        dev_err(DEV,
-                                "ASSERT FAILED: disk is %s while going diskless\n",
-                                drbd_disk_str(mdev->state.disk));
-
-                mdev->rs_total = 0;
-                mdev->rs_failed = 0;
-                atomic_set(&mdev->rs_pending_cnt, 0);
-
-		if (drbd_send_state(mdev))
-			dev_warn(DEV, "Notified peer that I'm now diskless.\n");
-		/* corresponding get_ldev in __drbd_set_state
-		 * this may finally trigger drbd_ldev_destroy. */
-		put_ldev(mdev);
-	}
-
-	/* Notify peer that I had a local IO error, and did not detached.. */
-	if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT)
-		drbd_send_state(mdev);
-
-	/* Disks got bigger while they were detached */
-	if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
-	    test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) {
-		if (ns.conn == C_CONNECTED)
-			resync_after_online_grow(mdev);
-	}
-
-	/* A resync finished or aborted, wake paused devices... */
-	if ((os.conn > C_CONNECTED && ns.conn <= C_CONNECTED) ||
-	    (os.peer_isp && !ns.peer_isp) ||
-	    (os.user_isp && !ns.user_isp))
-		resume_next_sg(mdev);
-
-	/* sync target done with resync.  Explicitly notify peer, even though
-	 * it should (at least for non-empty resyncs) already know itself. */
-	if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
-		drbd_send_state(mdev);
-
-	/* This triggers bitmap writeout of potentially still unwritten pages
-	 * if the resync finished cleanly, or aborted because of peer disk
-	 * failure, or because of connection loss.
-	 * For resync aborted because of local disk failure, we cannot do
-	 * any bitmap writeout anymore.
-	 * No harm done if some bits change during this phase.
-	 */
-	if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) {
-		drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL,
-			"write from resync_finished", BM_LOCKED_SET_ALLOWED);
-		put_ldev(mdev);
-	}
-
-	/* Upon network connection, we need to start the receiver */
-	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
-		drbd_thread_start(&mdev->tconn->receiver);
-
-	/* Terminate worker thread if we are unconfigured - it will be
-	   restarted as needed... */
-	if (ns.disk == D_DISKLESS &&
-	    ns.conn == C_STANDALONE &&
-	    ns.role == R_SECONDARY) {
-		if (os.aftr_isp != ns.aftr_isp)
-			resume_next_sg(mdev);
-		/* set in __drbd_set_state, unless CONFIG_PENDING was set */
-		if (test_bit(DEVICE_DYING, &mdev->flags))
-			drbd_thread_stop_nowait(&mdev->tconn->worker);
-	}
-
-	drbd_md_sync(mdev);
-}
-
-
 static int drbd_thread_setup(void *arg)
 {
 	struct drbd_thread *thi = (struct drbd_thread *) arg;
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
new file mode 100644
index 0000000..38d330b
--- /dev/null
+++ b/drivers/block/drbd/drbd_state.c
@@ -0,0 +1,1217 @@
+/*
+   drbd_state.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   Thanks to Carter Burden, Bart Grantham and Gennadiy Nerubayev
+   from Logicworks, Inc. for making SDP replication support possible.
+
+   drbd is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/drbd_limits.h>
+#include "drbd_int.h"
+#include "drbd_req.h"
+
+struct after_state_chg_work {
+	struct drbd_work w;
+	union drbd_state os;
+	union drbd_state ns;
+	enum chg_state_flags flags;
+	struct completion *done;
+};
+
+
+extern void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
+int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state);
+static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
+			   union drbd_state ns, enum chg_state_flags flags);
+static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
+				union drbd_state ns, enum chg_state_flags flags);
+static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
+static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, const char **warn_sync_abort);
+
+/**
+ * cl_wide_st_chg() - true if the state change is a cluster wide one
+ * @mdev:	DRBD device.
+ * @os:		old (current) state.
+ * @ns:		new (wanted) state.
+ */
+static int cl_wide_st_chg(struct drbd_conf *mdev,
+			  union drbd_state os, union drbd_state ns)
+{
+	return (os.conn >= C_CONNECTED && ns.conn >= C_CONNECTED &&
+		 ((os.role != R_PRIMARY && ns.role == R_PRIMARY) ||
+		  (os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
+		  (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S) ||
+		  (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))) ||
+		(os.conn >= C_CONNECTED && ns.conn == C_DISCONNECTING) ||
+		(os.conn == C_CONNECTED && ns.conn == C_VERIFY_S);
+}
+
+enum drbd_state_rv
+drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
+		  union drbd_state mask, union drbd_state val)
+{
+	unsigned long flags;
+	union drbd_state os, ns;
+	enum drbd_state_rv rv;
+
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	rv = _drbd_set_state(mdev, ns, f, NULL);
+	ns = mdev->state;
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
+
+	return rv;
+}
+
+/**
+ * drbd_force_state() - Impose a change which happens outside our control on our state
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ */
+void drbd_force_state(struct drbd_conf *mdev,
+	union drbd_state mask, union drbd_state val)
+{
+	drbd_change_state(mdev, CS_HARD, mask, val);
+}
+
+static enum drbd_state_rv
+_req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
+	     union drbd_state val)
+{
+	union drbd_state os, ns;
+	unsigned long flags;
+	enum drbd_state_rv rv;
+
+	if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags))
+		return SS_CW_SUCCESS;
+
+	if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags))
+		return SS_CW_FAILED_BY_PEER;
+
+	rv = 0;
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	ns = sanitize_state(mdev, os, ns, NULL);
+
+	if (!cl_wide_st_chg(mdev, os, ns))
+		rv = SS_CW_NO_NEED;
+	if (!rv) {
+		rv = is_valid_state(mdev, ns);
+		if (rv == SS_SUCCESS) {
+			rv = is_valid_soft_transition(os, ns);
+			if (rv == SS_SUCCESS)
+				rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
+		}
+	}
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
+
+	return rv;
+}
+
+/**
+ * drbd_req_state() - Perform an eventually cluster wide state change
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ * @f:		flags
+ *
+ * Should not be called directly, use drbd_request_state() or
+ * _drbd_request_state().
+ */
+static enum drbd_state_rv
+drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
+	       union drbd_state val, enum chg_state_flags f)
+{
+	struct completion done;
+	unsigned long flags;
+	union drbd_state os, ns;
+	enum drbd_state_rv rv;
+
+	init_completion(&done);
+
+	if (f & CS_SERIALIZE)
+		mutex_lock(&mdev->state_mutex);
+
+	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+
+	ns = sanitize_state(mdev, os, ns, NULL);
+
+	if (cl_wide_st_chg(mdev, os, ns)) {
+		rv = is_valid_state(mdev, ns);
+		if (rv == SS_SUCCESS)
+			rv = is_valid_soft_transition(os, ns);
+		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
+
+		if (rv < SS_SUCCESS) {
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+
+		drbd_state_lock(mdev);
+		if (!drbd_send_state_req(mdev, mask, val)) {
+			drbd_state_unlock(mdev);
+			rv = SS_CW_FAILED_BY_PEER;
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+
+		wait_event(mdev->state_wait,
+			(rv = _req_st_cond(mdev, mask, val)));
+
+		if (rv < SS_SUCCESS) {
+			drbd_state_unlock(mdev);
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
+		os = mdev->state;
+		ns.i = (os.i & ~mask.i) | val.i;
+		rv = _drbd_set_state(mdev, ns, f, &done);
+		drbd_state_unlock(mdev);
+	} else {
+		rv = _drbd_set_state(mdev, ns, f, &done);
+	}
+
+	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
+
+	if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
+		D_ASSERT(current != mdev->tconn->worker.task);
+		wait_for_completion(&done);
+	}
+
+abort:
+	if (f & CS_SERIALIZE)
+		mutex_unlock(&mdev->state_mutex);
+
+	return rv;
+}
+
+/**
+ * _drbd_request_state() - Request a state change (with flags)
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ * @f:		flags
+ *
+ * Cousin of drbd_request_state(), useful with the CS_WAIT_COMPLETE
+ * flag, or when logging of failed state change requests is not desired.
+ */
+enum drbd_state_rv
+_drbd_request_state(struct drbd_conf *mdev, union drbd_state mask,
+		    union drbd_state val, enum chg_state_flags f)
+{
+	enum drbd_state_rv rv;
+
+	wait_event(mdev->state_wait,
+		   (rv = drbd_req_state(mdev, mask, val, f)) != SS_IN_TRANSIENT_STATE);
+
+	return rv;
+}
+
+static void print_st(struct drbd_conf *mdev, char *name, union drbd_state ns)
+{
+	dev_err(DEV, " %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c%c%c }\n",
+	    name,
+	    drbd_conn_str(ns.conn),
+	    drbd_role_str(ns.role),
+	    drbd_role_str(ns.peer),
+	    drbd_disk_str(ns.disk),
+	    drbd_disk_str(ns.pdsk),
+	    is_susp(ns) ? 's' : 'r',
+	    ns.aftr_isp ? 'a' : '-',
+	    ns.peer_isp ? 'p' : '-',
+	    ns.user_isp ? 'u' : '-',
+	    ns.susp_fen ? 'F' : '-',
+	    ns.susp_nod ? 'N' : '-'
+	    );
+}
+
+void print_st_err(struct drbd_conf *mdev, union drbd_state os,
+	          union drbd_state ns, enum drbd_state_rv err)
+{
+	if (err == SS_IN_TRANSIENT_STATE)
+		return;
+	dev_err(DEV, "State change failed: %s\n", drbd_set_st_err_str(err));
+	print_st(mdev, " state", os);
+	print_st(mdev, "wanted", ns);
+}
+
+
+/**
+ * is_valid_state() - Returns an SS_ error code if ns is not valid
+ * @mdev:	DRBD device.
+ * @ns:		State to consider.
+ */
+static enum drbd_state_rv
+is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
+{
+	/* See drbd_state_sw_errors in drbd_strings.c */
+
+	enum drbd_fencing_p fp;
+	enum drbd_state_rv rv = SS_SUCCESS;
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	if (get_net_conf(mdev->tconn)) {
+		if (!mdev->tconn->net_conf->two_primaries &&
+		    ns.role == R_PRIMARY && ns.peer == R_PRIMARY)
+			rv = SS_TWO_PRIMARIES;
+		put_net_conf(mdev->tconn);
+	}
+
+	if (rv <= 0)
+		/* already found a reason to abort */;
+	else if (ns.role == R_SECONDARY && mdev->open_cnt)
+		rv = SS_DEVICE_IN_USE;
+
+	else if (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.disk < D_UP_TO_DATE)
+		rv = SS_NO_UP_TO_DATE_DISK;
+
+	else if (fp >= FP_RESOURCE &&
+		 ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk >= D_UNKNOWN)
+		rv = SS_PRIMARY_NOP;
+
+	else if (ns.role == R_PRIMARY && ns.disk <= D_INCONSISTENT && ns.pdsk <= D_INCONSISTENT)
+		rv = SS_NO_UP_TO_DATE_DISK;
+
+	else if (ns.conn > C_CONNECTED && ns.disk < D_INCONSISTENT)
+		rv = SS_NO_LOCAL_DISK;
+
+	else if (ns.conn > C_CONNECTED && ns.pdsk < D_INCONSISTENT)
+		rv = SS_NO_REMOTE_DISK;
+
+	else if (ns.conn > C_CONNECTED && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE)
+		rv = SS_NO_UP_TO_DATE_DISK;
+
+	else if ((ns.conn == C_CONNECTED ||
+		  ns.conn == C_WF_BITMAP_S ||
+		  ns.conn == C_SYNC_SOURCE ||
+		  ns.conn == C_PAUSED_SYNC_S) &&
+		  ns.disk == D_OUTDATED)
+		rv = SS_CONNECTED_OUTDATES;
+
+	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+		 (mdev->sync_conf.verify_alg[0] == 0))
+		rv = SS_NO_VERIFY_ALG;
+
+	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+		  mdev->tconn->agreed_pro_version < 88)
+		rv = SS_NOT_SUPPORTED;
+
+	else if (ns.conn >= C_CONNECTED && ns.pdsk == D_UNKNOWN)
+		rv = SS_CONNECTED_OUTDATES;
+
+	return rv;
+}
+
+/**
+ * is_valid_soft_transition() - Returns an SS_ error code if the state transition is not possible
+ * @mdev:	DRBD device.
+ * @ns:		new state.
+ * @os:		old state.
+ */
+static enum drbd_state_rv
+is_valid_soft_transition(union drbd_state os, union drbd_state ns)
+{
+	enum drbd_state_rv rv = SS_SUCCESS;
+
+	if ((ns.conn == C_STARTING_SYNC_T || ns.conn == C_STARTING_SYNC_S) &&
+	    os.conn > C_CONNECTED)
+		rv = SS_RESYNC_RUNNING;
+
+	if (ns.conn == C_DISCONNECTING && os.conn == C_STANDALONE)
+		rv = SS_ALREADY_STANDALONE;
+
+	if (ns.disk > D_ATTACHING && os.disk == D_DISKLESS)
+		rv = SS_IS_DISKLESS;
+
+	if (ns.conn == C_WF_CONNECTION && os.conn < C_UNCONNECTED)
+		rv = SS_NO_NET_CONFIG;
+
+	if (ns.disk == D_OUTDATED && os.disk < D_OUTDATED && os.disk != D_ATTACHING)
+		rv = SS_LOWER_THAN_OUTDATED;
+
+	if (ns.conn == C_DISCONNECTING && os.conn == C_UNCONNECTED)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	if (ns.conn == os.conn && ns.conn == C_WF_REPORT_PARAMS)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && os.conn < C_CONNECTED)
+		rv = SS_NEED_CONNECTION;
+
+	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+	    ns.conn != os.conn && os.conn > C_CONNECTED)
+		rv = SS_RESYNC_RUNNING;
+
+	if ((ns.conn == C_STARTING_SYNC_S || ns.conn == C_STARTING_SYNC_T) &&
+	    os.conn < C_CONNECTED)
+		rv = SS_NEED_CONNECTION;
+
+	if ((ns.conn == C_SYNC_TARGET || ns.conn == C_SYNC_SOURCE)
+	    && os.conn < C_WF_REPORT_PARAMS)
+		rv = SS_NEED_CONNECTION; /* No NetworkFailure -> SyncTarget etc... */
+
+	return rv;
+}
+
+/**
+ * sanitize_state() - Resolves implicitly necessary additional changes to a state transition
+ * @mdev:	DRBD device.
+ * @os:		old state.
+ * @ns:		new state.
+ * @warn_sync_abort:
+ *
+ * When we loose connection, we have to set the state of the peers disk (pdsk)
+ * to D_UNKNOWN. This rule and many more along those lines are in this function.
+ */
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, const char **warn_sync_abort)
+{
+	enum drbd_fencing_p fp;
+	enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max;
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	/* Disallow Network errors to configure a device's network part */
+	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
+	    os.conn <= C_DISCONNECTING)
+		ns.conn = os.conn;
+
+	/* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow.
+	 * If you try to go into some Sync* state, that shall fail (elsewhere). */
+	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
+	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN)
+		ns.conn = os.conn;
+
+	/* we cannot fail (again) if we already detached */
+	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
+		ns.disk = D_DISKLESS;
+
+	/* if we are only D_ATTACHING yet,
+	 * we can (and should) go directly to D_DISKLESS. */
+	if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
+		ns.disk = D_DISKLESS;
+
+	/* After C_DISCONNECTING only C_STANDALONE may follow */
+	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
+		ns.conn = os.conn;
+
+	if (ns.conn < C_CONNECTED) {
+		ns.peer_isp = 0;
+		ns.peer = R_UNKNOWN;
+		if (ns.pdsk > D_UNKNOWN || ns.pdsk < D_INCONSISTENT)
+			ns.pdsk = D_UNKNOWN;
+	}
+
+	/* Clear the aftr_isp when becoming unconfigured */
+	if (ns.conn == C_STANDALONE && ns.disk == D_DISKLESS && ns.role == R_SECONDARY)
+		ns.aftr_isp = 0;
+
+	/* Abort resync if a disk fails/detaches */
+	if (os.conn > C_CONNECTED && ns.conn > C_CONNECTED &&
+	    (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
+		if (warn_sync_abort)
+			*warn_sync_abort =
+				os.conn == C_VERIFY_S || os.conn == C_VERIFY_T ?
+				"Online-verify" : "Resync";
+		ns.conn = C_CONNECTED;
+	}
+
+	/* Connection breaks down before we finished "Negotiating" */
+	if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING &&
+	    get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		if (mdev->ed_uuid == mdev->ldev->md.uuid[UI_CURRENT]) {
+			ns.disk = mdev->new_state_tmp.disk;
+			ns.pdsk = mdev->new_state_tmp.pdsk;
+		} else {
+			dev_alert(DEV, "Connection lost while negotiating, no data!\n");
+			ns.disk = D_DISKLESS;
+			ns.pdsk = D_UNKNOWN;
+		}
+		put_ldev(mdev);
+	}
+
+	/* D_CONSISTENT and D_OUTDATED vanish when we get connected */
+	if (ns.conn >= C_CONNECTED && ns.conn < C_AHEAD) {
+		if (ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED)
+			ns.disk = D_UP_TO_DATE;
+		if (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED)
+			ns.pdsk = D_UP_TO_DATE;
+	}
+
+	/* Implications of the connection stat on the disk states */
+	disk_min = D_DISKLESS;
+	disk_max = D_UP_TO_DATE;
+	pdsk_min = D_INCONSISTENT;
+	pdsk_max = D_UNKNOWN;
+	switch ((enum drbd_conns)ns.conn) {
+	case C_WF_BITMAP_T:
+	case C_PAUSED_SYNC_T:
+	case C_STARTING_SYNC_T:
+	case C_WF_SYNC_UUID:
+	case C_BEHIND:
+		disk_min = D_INCONSISTENT;
+		disk_max = D_OUTDATED;
+		pdsk_min = D_UP_TO_DATE;
+		pdsk_max = D_UP_TO_DATE;
+		break;
+	case C_VERIFY_S:
+	case C_VERIFY_T:
+		disk_min = D_UP_TO_DATE;
+		disk_max = D_UP_TO_DATE;
+		pdsk_min = D_UP_TO_DATE;
+		pdsk_max = D_UP_TO_DATE;
+		break;
+	case C_CONNECTED:
+		disk_min = D_DISKLESS;
+		disk_max = D_UP_TO_DATE;
+		pdsk_min = D_DISKLESS;
+		pdsk_max = D_UP_TO_DATE;
+		break;
+	case C_WF_BITMAP_S:
+	case C_PAUSED_SYNC_S:
+	case C_STARTING_SYNC_S:
+	case C_AHEAD:
+		disk_min = D_UP_TO_DATE;
+		disk_max = D_UP_TO_DATE;
+		pdsk_min = D_INCONSISTENT;
+		pdsk_max = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/
+		break;
+	case C_SYNC_TARGET:
+		disk_min = D_INCONSISTENT;
+		disk_max = D_INCONSISTENT;
+		pdsk_min = D_UP_TO_DATE;
+		pdsk_max = D_UP_TO_DATE;
+		break;
+	case C_SYNC_SOURCE:
+		disk_min = D_UP_TO_DATE;
+		disk_max = D_UP_TO_DATE;
+		pdsk_min = D_INCONSISTENT;
+		pdsk_max = D_INCONSISTENT;
+		break;
+	case C_STANDALONE:
+	case C_DISCONNECTING:
+	case C_UNCONNECTED:
+	case C_TIMEOUT:
+	case C_BROKEN_PIPE:
+	case C_NETWORK_FAILURE:
+	case C_PROTOCOL_ERROR:
+	case C_TEAR_DOWN:
+	case C_WF_CONNECTION:
+	case C_WF_REPORT_PARAMS:
+	case C_MASK:
+		break;
+	}
+	if (ns.disk > disk_max)
+		ns.disk = disk_max;
+
+	if (ns.disk < disk_min) {
+		dev_warn(DEV, "Implicitly set disk from %s to %s\n",
+			 drbd_disk_str(ns.disk), drbd_disk_str(disk_min));
+		ns.disk = disk_min;
+	}
+	if (ns.pdsk > pdsk_max)
+		ns.pdsk = pdsk_max;
+
+	if (ns.pdsk < pdsk_min) {
+		dev_warn(DEV, "Implicitly set pdsk from %s to %s\n",
+			 drbd_disk_str(ns.pdsk), drbd_disk_str(pdsk_min));
+		ns.pdsk = pdsk_min;
+	}
+
+	if (fp == FP_STONITH &&
+	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
+	    !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
+		ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
+
+	if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
+	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
+	    !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
+		ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
+
+	if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
+		if (ns.conn == C_SYNC_SOURCE)
+			ns.conn = C_PAUSED_SYNC_S;
+		if (ns.conn == C_SYNC_TARGET)
+			ns.conn = C_PAUSED_SYNC_T;
+	} else {
+		if (ns.conn == C_PAUSED_SYNC_S)
+			ns.conn = C_SYNC_SOURCE;
+		if (ns.conn == C_PAUSED_SYNC_T)
+			ns.conn = C_SYNC_TARGET;
+	}
+
+	return ns;
+}
+
+void drbd_resume_al(struct drbd_conf *mdev)
+{
+	if (test_and_clear_bit(AL_SUSPENDED, &mdev->flags))
+		dev_info(DEV, "Resumed AL updates\n");
+}
+
+/* helper for __drbd_set_state */
+static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs)
+{
+	if (mdev->tconn->agreed_pro_version < 90)
+		mdev->ov_start_sector = 0;
+	mdev->rs_total = drbd_bm_bits(mdev);
+	mdev->ov_position = 0;
+	if (cs == C_VERIFY_T) {
+		/* starting online verify from an arbitrary position
+		 * does not fit well into the existing protocol.
+		 * on C_VERIFY_T, we initialize ov_left and friends
+		 * implicitly in receive_DataRequest once the
+		 * first P_OV_REQUEST is received */
+		mdev->ov_start_sector = ~(sector_t)0;
+	} else {
+		unsigned long bit = BM_SECT_TO_BIT(mdev->ov_start_sector);
+		if (bit >= mdev->rs_total) {
+			mdev->ov_start_sector =
+				BM_BIT_TO_SECT(mdev->rs_total - 1);
+			mdev->rs_total = 1;
+		} else
+			mdev->rs_total -= bit;
+		mdev->ov_position = mdev->ov_start_sector;
+	}
+	mdev->ov_left = mdev->rs_total;
+}
+
+/**
+ * __drbd_set_state() - Set a new DRBD state
+ * @mdev:	DRBD device.
+ * @ns:		new state.
+ * @flags:	Flags
+ * @done:	Optional completion, that will get completed after the after_state_ch() finished
+ *
+ * Caller needs to hold req_lock, and global_state_lock. Do not call directly.
+ */
+enum drbd_state_rv
+__drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
+	         enum chg_state_flags flags, struct completion *done)
+{
+	union drbd_state os;
+	enum drbd_state_rv rv = SS_SUCCESS;
+	const char *warn_sync_abort = NULL;
+	struct after_state_chg_work *ascw;
+
+	os = mdev->state;
+
+	ns = sanitize_state(mdev, os, ns, &warn_sync_abort);
+
+	if (ns.i == os.i)
+		return SS_NOTHING_TO_DO;
+
+	if (!(flags & CS_HARD)) {
+		/*  pre-state-change checks ; only look at ns  */
+		/* See drbd_state_sw_errors in drbd_strings.c */
+
+		rv = is_valid_state(mdev, ns);
+		if (rv < SS_SUCCESS) {
+			/* If the old state was illegal as well, then let
+			   this happen...*/
+
+			if (is_valid_state(mdev, os) == rv)
+				rv = is_valid_soft_transition(os, ns);
+		} else
+			rv = is_valid_soft_transition(os, ns);
+	}
+
+	if (rv < SS_SUCCESS) {
+		if (flags & CS_VERBOSE)
+			print_st_err(mdev, os, ns, rv);
+		return rv;
+	}
+
+	if (warn_sync_abort)
+		dev_warn(DEV, "%s aborted.\n", warn_sync_abort);
+
+	{
+	char *pbp, pb[300];
+	pbp = pb;
+	*pbp = 0;
+	if (ns.role != os.role)
+		pbp += sprintf(pbp, "role( %s -> %s ) ",
+			       drbd_role_str(os.role),
+			       drbd_role_str(ns.role));
+	if (ns.peer != os.peer)
+		pbp += sprintf(pbp, "peer( %s -> %s ) ",
+			       drbd_role_str(os.peer),
+			       drbd_role_str(ns.peer));
+	if (ns.conn != os.conn)
+		pbp += sprintf(pbp, "conn( %s -> %s ) ",
+			       drbd_conn_str(os.conn),
+			       drbd_conn_str(ns.conn));
+	if (ns.disk != os.disk)
+		pbp += sprintf(pbp, "disk( %s -> %s ) ",
+			       drbd_disk_str(os.disk),
+			       drbd_disk_str(ns.disk));
+	if (ns.pdsk != os.pdsk)
+		pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
+			       drbd_disk_str(os.pdsk),
+			       drbd_disk_str(ns.pdsk));
+	if (is_susp(ns) != is_susp(os))
+		pbp += sprintf(pbp, "susp( %d -> %d ) ",
+			       is_susp(os),
+			       is_susp(ns));
+	if (ns.aftr_isp != os.aftr_isp)
+		pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ",
+			       os.aftr_isp,
+			       ns.aftr_isp);
+	if (ns.peer_isp != os.peer_isp)
+		pbp += sprintf(pbp, "peer_isp( %d -> %d ) ",
+			       os.peer_isp,
+			       ns.peer_isp);
+	if (ns.user_isp != os.user_isp)
+		pbp += sprintf(pbp, "user_isp( %d -> %d ) ",
+			       os.user_isp,
+			       ns.user_isp);
+	dev_info(DEV, "%s\n", pb);
+	}
+
+	/* solve the race between becoming unconfigured,
+	 * worker doing the cleanup, and
+	 * admin reconfiguring us:
+	 * on (re)configure, first set CONFIG_PENDING,
+	 * then wait for a potentially exiting worker,
+	 * start the worker, and schedule one no_op.
+	 * then proceed with configuration.
+	 */
+	if (ns.disk == D_DISKLESS &&
+	    ns.conn == C_STANDALONE &&
+	    ns.role == R_SECONDARY &&
+	    !test_and_set_bit(CONFIG_PENDING, &mdev->flags))
+		set_bit(DEVICE_DYING, &mdev->flags);
+
+	/* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
+	 * on the ldev here, to be sure the transition -> D_DISKLESS resp.
+	 * drbd_ldev_destroy() won't happen before our corresponding
+	 * after_state_ch works run, where we put_ldev again. */
+	if ((os.disk != D_FAILED && ns.disk == D_FAILED) ||
+	    (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
+		atomic_inc(&mdev->local_cnt);
+
+	mdev->state = ns;
+
+	if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)
+		drbd_print_uuids(mdev, "attached to UUIDs");
+
+	wake_up(&mdev->misc_wait);
+	wake_up(&mdev->state_wait);
+
+	/* aborted verify run. log the last position */
+	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
+	    ns.conn < C_CONNECTED) {
+		mdev->ov_start_sector =
+			BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left);
+		dev_info(DEV, "Online Verify reached sector %llu\n",
+			(unsigned long long)mdev->ov_start_sector);
+	}
+
+	if ((os.conn == C_PAUSED_SYNC_T || os.conn == C_PAUSED_SYNC_S) &&
+	    (ns.conn == C_SYNC_TARGET  || ns.conn == C_SYNC_SOURCE)) {
+		dev_info(DEV, "Syncer continues.\n");
+		mdev->rs_paused += (long)jiffies
+				  -(long)mdev->rs_mark_time[mdev->rs_last_mark];
+		if (ns.conn == C_SYNC_TARGET)
+			mod_timer(&mdev->resync_timer, jiffies);
+	}
+
+	if ((os.conn == C_SYNC_TARGET  || os.conn == C_SYNC_SOURCE) &&
+	    (ns.conn == C_PAUSED_SYNC_T || ns.conn == C_PAUSED_SYNC_S)) {
+		dev_info(DEV, "Resync suspended\n");
+		mdev->rs_mark_time[mdev->rs_last_mark] = jiffies;
+	}
+
+	if (os.conn == C_CONNECTED &&
+	    (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T)) {
+		unsigned long now = jiffies;
+		int i;
+
+		set_ov_position(mdev, ns.conn);
+		mdev->rs_start = now;
+		mdev->rs_last_events = 0;
+		mdev->rs_last_sect_ev = 0;
+		mdev->ov_last_oos_size = 0;
+		mdev->ov_last_oos_start = 0;
+
+		for (i = 0; i < DRBD_SYNC_MARKS; i++) {
+			mdev->rs_mark_left[i] = mdev->ov_left;
+			mdev->rs_mark_time[i] = now;
+		}
+
+		drbd_rs_controller_reset(mdev);
+
+		if (ns.conn == C_VERIFY_S) {
+			dev_info(DEV, "Starting Online Verify from sector %llu\n",
+					(unsigned long long)mdev->ov_position);
+			mod_timer(&mdev->resync_timer, jiffies);
+		}
+	}
+
+	if (get_ldev(mdev)) {
+		u32 mdf = mdev->ldev->md.flags & ~(MDF_CONSISTENT|MDF_PRIMARY_IND|
+						 MDF_CONNECTED_IND|MDF_WAS_UP_TO_DATE|
+						 MDF_PEER_OUT_DATED|MDF_CRASHED_PRIMARY);
+
+		if (test_bit(CRASHED_PRIMARY, &mdev->flags))
+			mdf |= MDF_CRASHED_PRIMARY;
+		if (mdev->state.role == R_PRIMARY ||
+		    (mdev->state.pdsk < D_INCONSISTENT && mdev->state.peer == R_PRIMARY))
+			mdf |= MDF_PRIMARY_IND;
+		if (mdev->state.conn > C_WF_REPORT_PARAMS)
+			mdf |= MDF_CONNECTED_IND;
+		if (mdev->state.disk > D_INCONSISTENT)
+			mdf |= MDF_CONSISTENT;
+		if (mdev->state.disk > D_OUTDATED)
+			mdf |= MDF_WAS_UP_TO_DATE;
+		if (mdev->state.pdsk <= D_OUTDATED && mdev->state.pdsk >= D_INCONSISTENT)
+			mdf |= MDF_PEER_OUT_DATED;
+		if (mdf != mdev->ldev->md.flags) {
+			mdev->ldev->md.flags = mdf;
+			drbd_md_mark_dirty(mdev);
+		}
+		if (os.disk < D_CONSISTENT && ns.disk >= D_CONSISTENT)
+			drbd_set_ed_uuid(mdev, mdev->ldev->md.uuid[UI_CURRENT]);
+		put_ldev(mdev);
+	}
+
+	/* Peer was forced D_UP_TO_DATE & R_PRIMARY, consider to resync */
+	if (os.disk == D_INCONSISTENT && os.pdsk == D_INCONSISTENT &&
+	    os.peer == R_SECONDARY && ns.peer == R_PRIMARY)
+		set_bit(CONSIDER_RESYNC, &mdev->flags);
+
+	/* Receiver should clean up itself */
+	if (os.conn != C_DISCONNECTING && ns.conn == C_DISCONNECTING)
+		drbd_thread_stop_nowait(&mdev->tconn->receiver);
+
+	/* Now the receiver finished cleaning up itself, it should die */
+	if (os.conn != C_STANDALONE && ns.conn == C_STANDALONE)
+		drbd_thread_stop_nowait(&mdev->tconn->receiver);
+
+	/* Upon network failure, we need to restart the receiver. */
+	if (os.conn > C_TEAR_DOWN &&
+	    ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
+		drbd_thread_restart_nowait(&mdev->tconn->receiver);
+
+	/* Resume AL writing if we get a connection */
+	if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
+		drbd_resume_al(mdev);
+
+	ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
+	if (ascw) {
+		ascw->os = os;
+		ascw->ns = ns;
+		ascw->flags = flags;
+		ascw->w.cb = w_after_state_ch;
+		ascw->done = done;
+		drbd_queue_work(&mdev->tconn->data.work, &ascw->w);
+	} else {
+		dev_warn(DEV, "Could not kmalloc an ascw\n");
+	}
+
+	return rv;
+}
+
+static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct after_state_chg_work *ascw =
+		container_of(w, struct after_state_chg_work, w);
+
+	after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags);
+	if (ascw->flags & CS_WAIT_COMPLETE) {
+		D_ASSERT(ascw->done != NULL);
+		complete(ascw->done);
+	}
+	kfree(ascw);
+
+	return 1;
+}
+
+static void abw_start_sync(struct drbd_conf *mdev, int rv)
+{
+	if (rv) {
+		dev_err(DEV, "Writing the bitmap failed not starting resync.\n");
+		_drbd_request_state(mdev, NS(conn, C_CONNECTED), CS_VERBOSE);
+		return;
+	}
+
+	switch (mdev->state.conn) {
+	case C_STARTING_SYNC_T:
+		_drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
+		break;
+	case C_STARTING_SYNC_S:
+		drbd_start_resync(mdev, C_SYNC_SOURCE);
+		break;
+	}
+}
+
+int drbd_bitmap_io_from_worker(struct drbd_conf *mdev,
+		int (*io_fn)(struct drbd_conf *),
+		char *why, enum bm_flag flags)
+{
+	int rv;
+
+	D_ASSERT(current == mdev->tconn->worker.task);
+
+	/* open coded non-blocking drbd_suspend_io(mdev); */
+	set_bit(SUSPEND_IO, &mdev->flags);
+
+	drbd_bm_lock(mdev, why, flags);
+	rv = io_fn(mdev);
+	drbd_bm_unlock(mdev);
+
+	drbd_resume_io(mdev);
+
+	return rv;
+}
+
+/**
+ * after_state_ch() - Perform after state change actions that may sleep
+ * @mdev:	DRBD device.
+ * @os:		old state.
+ * @ns:		new state.
+ * @flags:	Flags
+ */
+static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
+			   union drbd_state ns, enum chg_state_flags flags)
+{
+	enum drbd_fencing_p fp;
+	enum drbd_req_event what = NOTHING;
+	union drbd_state nsm = (union drbd_state){ .i = -1 };
+
+	if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
+		clear_bit(CRASHED_PRIMARY, &mdev->flags);
+		if (mdev->p_uuid)
+			mdev->p_uuid[UI_FLAGS] &= ~((u64)2);
+	}
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	/* Inform userspace about the change... */
+	drbd_bcast_state(mdev, ns);
+
+	if (!(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE) &&
+	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
+		drbd_khelper(mdev, "pri-on-incon-degr");
+
+	/* Here we have the actions that are performed after a
+	   state change. This function might sleep */
+
+	nsm.i = -1;
+	if (ns.susp_nod) {
+		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
+			what = RESEND;
+
+		if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
+			what = RESTART_FROZEN_DISK_IO;
+
+		if (what != NOTHING)
+			nsm.susp_nod = 0;
+	}
+
+	if (ns.susp_fen) {
+		/* case1: The outdate peer handler is successful: */
+		if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) {
+			tl_clear(mdev);
+			if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
+				drbd_uuid_new_current(mdev);
+				clear_bit(NEW_CUR_UUID, &mdev->flags);
+			}
+			spin_lock_irq(&mdev->tconn->req_lock);
+			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
+			spin_unlock_irq(&mdev->tconn->req_lock);
+		}
+		/* case2: The connection was established again: */
+		if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
+			clear_bit(NEW_CUR_UUID, &mdev->flags);
+			what = RESEND;
+			nsm.susp_fen = 0;
+		}
+	}
+
+	if (what != NOTHING) {
+		spin_lock_irq(&mdev->tconn->req_lock);
+		_tl_restart(mdev, what);
+		nsm.i &= mdev->state.i;
+		_drbd_set_state(mdev, nsm, CS_VERBOSE, NULL);
+		spin_unlock_irq(&mdev->tconn->req_lock);
+	}
+
+	/* Became sync source.  With protocol >= 96, we still need to send out
+	 * the sync uuid now. Need to do that before any drbd_send_state, or
+	 * the other side may go "paused sync" before receiving the sync uuids,
+	 * which is unexpected. */
+	if ((os.conn != C_SYNC_SOURCE && os.conn != C_PAUSED_SYNC_S) &&
+	    (ns.conn == C_SYNC_SOURCE || ns.conn == C_PAUSED_SYNC_S) &&
+	    mdev->tconn->agreed_pro_version >= 96 && get_ldev(mdev)) {
+		drbd_gen_and_send_sync_uuid(mdev);
+		put_ldev(mdev);
+	}
+
+	/* Do not change the order of the if above and the two below... */
+	if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) {      /* attach on the peer */
+		drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+	}
+	/* No point in queuing send_bitmap if we don't have a connection
+	 * anymore, so check also the _current_ state, not only the new state
+	 * at the time this work was queued. */
+	if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S &&
+	    mdev->state.conn == C_WF_BITMAP_S)
+		drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL,
+				"send_bitmap (WFBitMapS)",
+				BM_LOCKED_TEST_ALLOWED);
+
+	/* Lost contact to peer's copy of the data */
+	if ((os.pdsk >= D_INCONSISTENT &&
+	     os.pdsk != D_UNKNOWN &&
+	     os.pdsk != D_OUTDATED)
+	&&  (ns.pdsk < D_INCONSISTENT ||
+	     ns.pdsk == D_UNKNOWN ||
+	     ns.pdsk == D_OUTDATED)) {
+		if (get_ldev(mdev)) {
+			if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
+			    mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
+				if (is_susp(mdev->state)) {
+					set_bit(NEW_CUR_UUID, &mdev->flags);
+				} else {
+					drbd_uuid_new_current(mdev);
+					drbd_send_uuids(mdev);
+				}
+			}
+			put_ldev(mdev);
+		}
+	}
+
+	if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) {
+		if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) {
+			drbd_uuid_new_current(mdev);
+			drbd_send_uuids(mdev);
+		}
+
+		/* D_DISKLESS Peer becomes secondary */
+		if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
+			/* We may still be Primary ourselves.
+			 * No harm done if the bitmap still changes,
+			 * redirtied pages will follow later. */
+			drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
+				"demote diskless peer", BM_LOCKED_SET_ALLOWED);
+		put_ldev(mdev);
+	}
+
+	/* Write out all changed bits on demote.
+	 * Though, no need to da that just yet
+	 * if there is a resync going on still */
+	if (os.role == R_PRIMARY && ns.role == R_SECONDARY &&
+		mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) {
+		/* No changes to the bitmap expected this time, so assert that,
+		 * even though no harm was done if it did change. */
+		drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
+				"demote", BM_LOCKED_TEST_ALLOWED);
+		put_ldev(mdev);
+	}
+
+	/* Last part of the attaching process ... */
+	if (ns.conn >= C_CONNECTED &&
+	    os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) {
+		drbd_send_sizes(mdev, 0, 0);  /* to start sync... */
+		drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+	}
+
+	/* We want to pause/continue resync, tell peer. */
+	if (ns.conn >= C_CONNECTED &&
+	     ((os.aftr_isp != ns.aftr_isp) ||
+	      (os.user_isp != ns.user_isp)))
+		drbd_send_state(mdev);
+
+	/* In case one of the isp bits got set, suspend other devices. */
+	if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) &&
+	    (ns.aftr_isp || ns.peer_isp || ns.user_isp))
+		suspend_other_sg(mdev);
+
+	/* Make sure the peer gets informed about eventual state
+	   changes (ISP bits) while we were in WFReportParams. */
+	if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
+		drbd_send_state(mdev);
+
+	if (os.conn != C_AHEAD && ns.conn == C_AHEAD)
+		drbd_send_state(mdev);
+
+	/* We are in the progress to start a full sync... */
+	if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
+	    (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S))
+		/* no other bitmap changes expected during this phase */
+		drbd_queue_bitmap_io(mdev,
+			&drbd_bmio_set_n_write, &abw_start_sync,
+			"set_n_write from StartingSync", BM_LOCKED_TEST_ALLOWED);
+
+	/* We are invalidating our self... */
+	if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED &&
+	    os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT)
+		/* other bitmap operation expected during this phase */
+		drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL,
+			"set_n_write from invalidate", BM_LOCKED_MASK);
+
+	/* first half of local IO error, failure to attach,
+	 * or administrative detach */
+	if (os.disk != D_FAILED && ns.disk == D_FAILED) {
+		enum drbd_io_error_p eh;
+		int was_io_error;
+		/* corresponding get_ldev was in __drbd_set_state, to serialize
+		 * our cleanup here with the transition to D_DISKLESS,
+		 * so it is safe to dreference ldev here. */
+		eh = mdev->ldev->dc.on_io_error;
+		was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
+
+		/* current state still has to be D_FAILED,
+		 * there is only one way out: to D_DISKLESS,
+		 * and that may only happen after our put_ldev below. */
+		if (mdev->state.disk != D_FAILED)
+			dev_err(DEV,
+				"ASSERT FAILED: disk is %s during detach\n",
+				drbd_disk_str(mdev->state.disk));
+
+		if (drbd_send_state(mdev))
+			dev_warn(DEV, "Notified peer that I am detaching my disk\n");
+		else
+			dev_err(DEV, "Sending state for detaching disk failed\n");
+
+		drbd_rs_cancel_all(mdev);
+
+		/* In case we want to get something to stable storage still,
+		 * this may be the last chance.
+		 * Following put_ldev may transition to D_DISKLESS. */
+		drbd_md_sync(mdev);
+		put_ldev(mdev);
+
+		if (was_io_error && eh == EP_CALL_HELPER)
+			drbd_khelper(mdev, "local-io-error");
+	}
+
+        /* second half of local IO error, failure to attach,
+         * or administrative detach,
+         * after local_cnt references have reached zero again */
+        if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) {
+                /* We must still be diskless,
+                 * re-attach has to be serialized with this! */
+                if (mdev->state.disk != D_DISKLESS)
+                        dev_err(DEV,
+                                "ASSERT FAILED: disk is %s while going diskless\n",
+                                drbd_disk_str(mdev->state.disk));
+
+                mdev->rs_total = 0;
+                mdev->rs_failed = 0;
+                atomic_set(&mdev->rs_pending_cnt, 0);
+
+		if (drbd_send_state(mdev))
+			dev_warn(DEV, "Notified peer that I'm now diskless.\n");
+		/* corresponding get_ldev in __drbd_set_state
+		 * this may finally trigger drbd_ldev_destroy. */
+		put_ldev(mdev);
+	}
+
+	/* Notify peer that I had a local IO error, and did not detached.. */
+	if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT)
+		drbd_send_state(mdev);
+
+	/* Disks got bigger while they were detached */
+	if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
+	    test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) {
+		if (ns.conn == C_CONNECTED)
+			resync_after_online_grow(mdev);
+	}
+
+	/* A resync finished or aborted, wake paused devices... */
+	if ((os.conn > C_CONNECTED && ns.conn <= C_CONNECTED) ||
+	    (os.peer_isp && !ns.peer_isp) ||
+	    (os.user_isp && !ns.user_isp))
+		resume_next_sg(mdev);
+
+	/* sync target done with resync.  Explicitly notify peer, even though
+	 * it should (at least for non-empty resyncs) already know itself. */
+	if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
+		drbd_send_state(mdev);
+
+	/* This triggers bitmap writeout of potentially still unwritten pages
+	 * if the resync finished cleanly, or aborted because of peer disk
+	 * failure, or because of connection loss.
+	 * For resync aborted because of local disk failure, we cannot do
+	 * any bitmap writeout anymore.
+	 * No harm done if some bits change during this phase.
+	 */
+	if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) {
+		drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL,
+			"write from resync_finished", BM_LOCKED_SET_ALLOWED);
+		put_ldev(mdev);
+	}
+
+	if (ns.disk == D_DISKLESS &&
+	    ns.conn == C_STANDALONE &&
+	    ns.role == R_SECONDARY) {
+		if (os.aftr_isp != ns.aftr_isp)
+			resume_next_sg(mdev);
+	}
+
+	after_conn_state_ch(mdev->tconn, os, ns, flags);
+	drbd_md_sync(mdev);
+}
+
+static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
+				union drbd_state ns, enum chg_state_flags flags)
+{
+	/* Upon network configuration, we need to start the receiver */
+	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
+		drbd_thread_start(&tconn->receiver);
+
+	if (ns.disk == D_DISKLESS &&
+	    ns.conn == C_STANDALONE &&
+	    ns.role == R_SECONDARY) {
+		/* if (test_bit(DEVICE_DYING, &mdev->flags)) TODO: DEVICE_DYING functionality */
+		drbd_thread_stop_nowait(&tconn->worker);
+	}
+}
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
new file mode 100644
index 0000000..3ec26e2
--- /dev/null
+++ b/drivers/block/drbd/drbd_state.h
@@ -0,0 +1,101 @@
+#ifndef DRBD_STATE_H
+#define DRBD_STATE_H
+
+struct drbd_conf;
+
+/**
+ * DOC: DRBD State macros
+ *
+ * These macros are used to express state changes in easily readable form.
+ *
+ * The NS macros expand to a mask and a value, that can be bit ored onto the
+ * current state as soon as the spinlock (req_lock) was taken.
+ *
+ * The _NS macros are used for state functions that get called with the
+ * spinlock. These macros expand directly to the new state value.
+ *
+ * Besides the basic forms NS() and _NS() additional _?NS[23] are defined
+ * to express state changes that affect more than one aspect of the state.
+ *
+ * E.g. NS2(conn, C_CONNECTED, peer, R_SECONDARY)
+ * Means that the network connection was established and that the peer
+ * is in secondary role.
+ */
+#define role_MASK R_MASK
+#define peer_MASK R_MASK
+#define disk_MASK D_MASK
+#define pdsk_MASK D_MASK
+#define conn_MASK C_MASK
+#define susp_MASK 1
+#define user_isp_MASK 1
+#define aftr_isp_MASK 1
+#define susp_nod_MASK 1
+#define susp_fen_MASK 1
+
+#define NS(T, S) \
+	({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \
+	({ union drbd_state val; val.i = 0; val.T = (S); val; })
+#define NS2(T1, S1, T2, S2) \
+	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
+	  mask.T2 = T2##_MASK; mask; }), \
+	({ union drbd_state val; val.i = 0; val.T1 = (S1); \
+	  val.T2 = (S2); val; })
+#define NS3(T1, S1, T2, S2, T3, S3) \
+	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
+	  mask.T2 = T2##_MASK; mask.T3 = T3##_MASK; mask; }), \
+	({ union drbd_state val;  val.i = 0; val.T1 = (S1); \
+	  val.T2 = (S2); val.T3 = (S3); val; })
+
+#define _NS(D, T, S) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T = (S); __ns; })
+#define _NS2(D, T1, S1, T2, S2) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	__ns.T2 = (S2); __ns; })
+#define _NS3(D, T1, S1, T2, S2, T3, S3) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	__ns.T2 = (S2); __ns.T3 = (S3); __ns; })
+
+enum chg_state_flags {
+	CS_HARD	= 1,
+	CS_VERBOSE = 2,
+	CS_WAIT_COMPLETE = 4,
+	CS_SERIALIZE    = 8,
+	CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
+};
+
+extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
+					    enum chg_state_flags f,
+					    union drbd_state mask,
+					    union drbd_state val);
+extern void drbd_force_state(struct drbd_conf *, union drbd_state,
+			union drbd_state);
+extern enum drbd_state_rv _drbd_request_state(struct drbd_conf *,
+					      union drbd_state,
+					      union drbd_state,
+					      enum chg_state_flags);
+extern enum drbd_state_rv __drbd_set_state(struct drbd_conf *, union drbd_state,
+					   enum chg_state_flags,
+					   struct completion *done);
+extern void print_st_err(struct drbd_conf *, union drbd_state,
+			union drbd_state, int);
+
+extern void drbd_resume_al(struct drbd_conf *mdev);
+
+/**
+ * drbd_request_state() - Reqest a state change
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ *
+ * This is the most graceful way of requesting a state change. It is verbose
+ * quite verbose in case the state change is not possible, and all those
+ * state changes are globally serialized.
+ */
+static inline int drbd_request_state(struct drbd_conf *mdev,
+				     union drbd_state mask,
+				     union drbd_state val)
+{
+	return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED);
+}
+
+#endif
-- 
1.7.4.1


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

* [PATCH 062/118] drbd: Moved the thread name into the data structure
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (60 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 061/118] drbd: Moved the state functions into its own source file Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:07 ` [PATCH 063/118] drbd: Eliminated the user of drbd_task_to_thread() Philipp Reisner
                   ` (57 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 4da4c32..e85221f 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -119,13 +119,9 @@ static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
 	if (!__ratelimit(&drbd_ratelimit_state))
 		return;
 	dev_err(DEV, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
-	    current == mdev->tconn->receiver.task ? "receiver" :
-	    current == mdev->tconn->asender.task  ? "asender"  :
-	    current == mdev->tconn->worker.task   ? "worker"   : current->comm,
-	    func, b->bm_why ?: "?",
-	    b->bm_task == mdev->tconn->receiver.task ? "receiver" :
-	    b->bm_task == mdev->tconn->asender.task  ? "asender"  :
-	    b->bm_task == mdev->tconn->worker.task   ? "worker"   : "?");
+		drbd_task_to_thread_name(mdev, current),
+		func, b->bm_why ?: "?",
+		drbd_task_to_thread_name(mdev, b->bm_task));
 }
 
 void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
@@ -142,13 +138,9 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
 
 	if (trylock_failed) {
 		dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
-		    current == mdev->tconn->receiver.task ? "receiver" :
-		    current == mdev->tconn->asender.task  ? "asender"  :
-		    current == mdev->tconn->worker.task   ? "worker"   : current->comm,
-		    why, b->bm_why ?: "?",
-		    b->bm_task == mdev->tconn->receiver.task ? "receiver" :
-		    b->bm_task == mdev->tconn->asender.task  ? "asender"  :
-		    b->bm_task == mdev->tconn->worker.task   ? "worker"   : "?");
+			 drbd_task_to_thread_name(mdev, current),
+			 why, b->bm_why ?: "?",
+			 drbd_task_to_thread_name(mdev, b->bm_task));
 		mutex_lock(&b->bm_change);
 	}
 	if (BM_LOCKED_MASK & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2c18cf3..fda9a4d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -616,6 +616,7 @@ struct drbd_thread {
 	int (*function) (struct drbd_thread *);
 	struct drbd_conf *mdev;
 	int reset_cpu_mask;
+	char name[9];
 };
 
 static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
@@ -1130,6 +1131,7 @@ enum dds_flags {
 extern void drbd_init_set_defaults(struct drbd_conf *mdev);
 extern int  drbd_thread_start(struct drbd_thread *thi);
 extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
+extern char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task);
 #ifdef CONFIG_SMP
 extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev);
 extern void drbd_calc_cpu_mask(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ccd57a9..5e9e57d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -462,7 +462,7 @@ restart:
 	 */
 
 	if (thi->t_state == RESTARTING) {
-		dev_info(DEV, "Restarting %s\n", current->comm);
+		dev_info(DEV, "Restarting %s thread\n", thi->name);
 		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		goto restart;
@@ -482,13 +482,14 @@ restart:
 }
 
 static void drbd_thread_init(struct drbd_conf *mdev, struct drbd_thread *thi,
-		      int (*func) (struct drbd_thread *))
+			     int (*func) (struct drbd_thread *), char *name)
 {
 	spin_lock_init(&thi->t_lock);
 	thi->task    = NULL;
 	thi->t_state = NONE;
 	thi->function = func;
 	thi->mdev = mdev;
+	strncpy(thi->name, name, ARRAY_SIZE(thi->name));
 }
 
 int drbd_thread_start(struct drbd_thread *thi)
@@ -497,11 +498,6 @@ int drbd_thread_start(struct drbd_thread *thi)
 	struct task_struct *nt;
 	unsigned long flags;
 
-	const char *me =
-		thi == &mdev->tconn->receiver ? "receiver" :
-		thi == &mdev->tconn->asender  ? "asender"  :
-		thi == &mdev->tconn->worker   ? "worker"   : "NONSENSE";
-
 	/* is used from state engine doing drbd_thread_stop_nowait,
 	 * while holding the req lock irqsave */
 	spin_lock_irqsave(&thi->t_lock, flags);
@@ -509,7 +505,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 	switch (thi->t_state) {
 	case NONE:
 		dev_info(DEV, "Starting %s thread (from %s [%d])\n",
-				me, current->comm, current->pid);
+			 thi->name, current->comm, current->pid);
 
 		/* Get ref on module for thread - this is released when thread exits */
 		if (!try_module_get(THIS_MODULE)) {
@@ -526,7 +522,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 		flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
 
 		nt = kthread_create(drbd_thread_setup, (void *) thi,
-				    "drbd%d_%s", mdev_to_minor(mdev), me);
+				    "drbd%d_%s", mdev_to_minor(mdev), thi->name);
 
 		if (IS_ERR(nt)) {
 			dev_err(DEV, "Couldn't start thread\n");
@@ -543,7 +539,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 	case EXITING:
 		thi->t_state = RESTARTING;
 		dev_info(DEV, "Restarting %s thread (from %s [%d])\n",
-				me, current->comm, current->pid);
+				thi->name, current->comm, current->pid);
 		/* fall through */
 	case RUNNING:
 	case RESTARTING:
@@ -592,6 +588,23 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
 		wait_for_completion(&thi->stop);
 }
 
+static struct drbd_thread *drbd_task_to_thread(struct drbd_conf *mdev, struct task_struct *task)
+{
+	struct drbd_tconn *tconn = mdev->tconn;
+	struct drbd_thread *thi =
+		task == tconn->receiver.task ? &tconn->receiver :
+		task == tconn->asender.task  ? &tconn->asender :
+		task == tconn->worker.task   ? &tconn->worker : NULL;
+
+	return thi;
+}
+
+char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task)
+{
+	struct drbd_thread *thi = drbd_task_to_thread(mdev, task);
+	return thi ? thi->name : task->comm;
+}
+
 #ifdef CONFIG_SMP
 /**
  * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
@@ -629,11 +642,8 @@ void drbd_calc_cpu_mask(struct drbd_conf *mdev)
 void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
 {
 	struct task_struct *p = current;
-	struct drbd_thread *thi =
-		p == mdev->tconn->asender.task  ? &mdev->tconn->asender  :
-		p == mdev->tconn->receiver.task ? &mdev->tconn->receiver :
-		p == mdev->tconn->worker.task   ? &mdev->tconn->worker   :
-		NULL;
+	struct drbd_thread *thi = drbd_task_to_thread(mdev, p);
+
 	if (!expect(thi != NULL))
 		return;
 	if (!thi->reset_cpu_mask)
@@ -1848,9 +1858,9 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	init_waitqueue_head(&mdev->al_wait);
 	init_waitqueue_head(&mdev->seq_wait);
 
-	drbd_thread_init(mdev, &mdev->tconn->receiver, drbdd_init);
-	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker);
-	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender);
+	drbd_thread_init(mdev, &mdev->tconn->receiver, drbdd_init, "receiver");
+	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker, "worker");
+	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender, "asender");
 
 	/* mdev->tconn->agreed_pro_version gets initialized in drbd_connect() */
 	mdev->write_ordering = WO_bdev_flush;
-- 
1.7.4.1


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

* [PATCH 063/118] drbd: Eliminated the user of drbd_task_to_thread()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (61 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 062/118] drbd: Moved the thread name into the data structure Philipp Reisner
@ 2011-08-25 15:07 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 064/118] drbd: Moved code Philipp Reisner
                   ` (56 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:07 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index fda9a4d..4dfbbbc 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1133,10 +1133,10 @@ extern int  drbd_thread_start(struct drbd_thread *thi);
 extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
 extern char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task);
 #ifdef CONFIG_SMP
-extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev);
+extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev, struct drbd_thread *thi);
 extern void drbd_calc_cpu_mask(struct drbd_conf *mdev);
 #else
-#define drbd_thread_current_set_cpu(A) ({})
+#define drbd_thread_current_set_cpu(A, B) ({})
 #define drbd_calc_cpu_mask(A) ({})
 #endif
 extern void drbd_free_resources(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 5e9e57d..ed43cdc 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -635,17 +635,15 @@ void drbd_calc_cpu_mask(struct drbd_conf *mdev)
 /**
  * drbd_thread_current_set_cpu() - modifies the cpu mask of the _current_ thread
  * @mdev:	DRBD device.
+ * @thi:	drbd_thread object
  *
  * call in the "main loop" of _all_ threads, no need for any mutex, current won't die
  * prematurely.
  */
-void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
+void drbd_thread_current_set_cpu(struct drbd_conf *mdev, struct drbd_thread *thi)
 {
 	struct task_struct *p = current;
-	struct drbd_thread *thi = drbd_task_to_thread(mdev, p);
 
-	if (!expect(thi != NULL))
-		return;
 	if (!thi->reset_cpu_mask)
 		return;
 	thi->reset_cpu_mask = 0;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 3f0f41f..78a05ec 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3777,7 +3777,7 @@ static void drbdd(struct drbd_conf *mdev)
 	int rv;
 
 	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev);
+		drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
 		if (!drbd_recv_header(mdev, &cmd, &packet_size))
 			goto err_out;
 
@@ -4568,7 +4568,7 @@ int drbd_asender(struct drbd_thread *thi)
 	current->rt_priority = 2;    /* more important than all other tasks */
 
 	while (get_t_state(thi) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev);
+		drbd_thread_current_set_cpu(mdev, thi);
 		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
 			if (!drbd_send_ping(mdev)) {
 				dev_err(DEV, "drbd_send_ping has failed\n");
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index f13d56c..0dbd20c 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1621,7 +1621,7 @@ int drbd_worker(struct drbd_thread *thi)
 	sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev));
 
 	while (get_t_state(thi) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev);
+		drbd_thread_current_set_cpu(mdev, thi);
 
 		if (down_trylock(&mdev->tconn->data.work.s)) {
 			mutex_lock(&mdev->tconn->data.mutex);
-- 
1.7.4.1


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

* [PATCH 064/118] drbd: Moved code
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (62 preceding siblings ...)
  2011-08-25 15:07 ` [PATCH 063/118] drbd: Eliminated the user of drbd_task_to_thread() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 065/118] drbd: Do no sleep long in drbd_start_resync Philipp Reisner
                   ` (55 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_worker.c |   43 ++++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 0dbd20c..28925d3 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -707,28 +707,6 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca
 	return 1;
 }
 
-
-void start_resync_timer_fn(unsigned long data)
-{
-	struct drbd_conf *mdev = (struct drbd_conf *) data;
-
-	drbd_queue_work(&mdev->tconn->data.work, &mdev->start_resync_work);
-}
-
-int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
-{
-	if (atomic_read(&mdev->unacked_cnt) || atomic_read(&mdev->rs_pending_cnt)) {
-		dev_warn(DEV, "w_start_resync later...\n");
-		mdev->start_resync_timer.expires = jiffies + HZ/10;
-		add_timer(&mdev->start_resync_timer);
-		return 1;
-	}
-
-	drbd_start_resync(mdev, C_SYNC_SOURCE);
-	clear_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags);
-	return 1;
-}
-
 int w_ov_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	kfree(w);
@@ -1462,6 +1440,27 @@ void drbd_rs_controller_reset(struct drbd_conf *mdev)
 	spin_unlock(&mdev->peer_seq_lock);
 }
 
+void start_resync_timer_fn(unsigned long data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *) data;
+
+	drbd_queue_work(&mdev->tconn->data.work, &mdev->start_resync_work);
+}
+
+int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	if (atomic_read(&mdev->unacked_cnt) || atomic_read(&mdev->rs_pending_cnt)) {
+		dev_warn(DEV, "w_start_resync later...\n");
+		mdev->start_resync_timer.expires = jiffies + HZ/10;
+		add_timer(&mdev->start_resync_timer);
+		return 1;
+	}
+
+	drbd_start_resync(mdev, C_SYNC_SOURCE);
+	clear_bit(AHEAD_TO_SYNC_SOURCE, &mdev->current_epoch->flags);
+	return 1;
+}
+
 /**
  * drbd_start_resync() - Start the resync process
  * @mdev:	DRBD device.
-- 
1.7.4.1


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

* [PATCH 065/118] drbd: Do no sleep long in drbd_start_resync
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (63 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 064/118] drbd: Moved code Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 066/118] drbd: Revert "Make sure we dont send state if a cluster wide state change is in progress" Philipp Reisner
                   ` (54 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Work items that sleep too long can cause requests to take as
long as the longest sleeping work item.

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_worker.c |   58 +++++++++++++++++++++++--------------
 2 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4dfbbbc..c625f59 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -787,6 +787,7 @@ enum {
 	NEW_CUR_UUID,		/* Create new current UUID when thawing IO */
 	AL_SUSPENDED,		/* Activity logging is currently suspended. */
 	AHEAD_TO_SYNC_SOURCE,   /* Ahead -> SyncSource queued */
+	B_RS_H_DONE,		/* Before resync handler done (already executed) */
 };
 
 struct drbd_bitmap; /* opaque for drbd_conf */
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 28925d3..a705979 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1487,35 +1487,49 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 		   Ahead/Behind and SyncSource/SyncTarget */
 	}
 
-	if (side == C_SYNC_TARGET) {
-		/* Since application IO was locked out during C_WF_BITMAP_T and
-		   C_WF_SYNC_UUID we are still unmodified. Before going to C_SYNC_TARGET
-		   we check that we might make the data inconsistent. */
-		r = drbd_khelper(mdev, "before-resync-target");
-		r = (r >> 8) & 0xff;
-		if (r > 0) {
-			dev_info(DEV, "before-resync-target handler returned %d, "
-			     "dropping connection.\n", r);
-			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
-			return;
-		}
-	} else /* C_SYNC_SOURCE */ {
-		r = drbd_khelper(mdev, "before-resync-source");
-		r = (r >> 8) & 0xff;
-		if (r > 0) {
-			if (r == 3) {
-				dev_info(DEV, "before-resync-source handler returned %d, "
-					 "ignoring. Old userland tools?", r);
-			} else {
-				dev_info(DEV, "before-resync-source handler returned %d, "
+	if (!test_bit(B_RS_H_DONE, &mdev->flags)) {
+		if (side == C_SYNC_TARGET) {
+			/* Since application IO was locked out during C_WF_BITMAP_T and
+			   C_WF_SYNC_UUID we are still unmodified. Before going to C_SYNC_TARGET
+			   we check that we might make the data inconsistent. */
+			r = drbd_khelper(mdev, "before-resync-target");
+			r = (r >> 8) & 0xff;
+			if (r > 0) {
+				dev_info(DEV, "before-resync-target handler returned %d, "
 					 "dropping connection.\n", r);
 				drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
 				return;
 			}
+		} else /* C_SYNC_SOURCE */ {
+			r = drbd_khelper(mdev, "before-resync-source");
+			r = (r >> 8) & 0xff;
+			if (r > 0) {
+				if (r == 3) {
+					dev_info(DEV, "before-resync-source handler returned %d, "
+						 "ignoring. Old userland tools?", r);
+				} else {
+					dev_info(DEV, "before-resync-source handler returned %d, "
+						 "dropping connection.\n", r);
+					drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+					return;
+				}
+			}
 		}
 	}
 
-	drbd_state_lock(mdev);
+	if (current == mdev->tconn->worker.task) {
+		/* The worker should not sleep waiting for drbd_state_lock(),
+		   that can take long */
+		if (test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags)) {
+			set_bit(B_RS_H_DONE, &mdev->flags);
+			mdev->start_resync_timer.expires = jiffies + HZ/5;
+			add_timer(&mdev->start_resync_timer);
+			return;
+		}
+	} else {
+		drbd_state_lock(mdev);
+	}
+	clear_bit(B_RS_H_DONE, &mdev->flags);
 
 	if (!get_ldev_if_state(mdev, D_NEGOTIATING)) {
 		drbd_state_unlock(mdev);
-- 
1.7.4.1


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

* [PATCH 066/118] drbd: Revert "Make sure we dont send state if a cluster wide state change is in progress"
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (64 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 065/118] drbd: Do no sleep long in drbd_start_resync Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 067/118] drbd: Moving state related macros to drbd_state.h Philipp Reisner
                   ` (53 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

This reverts commit 6e9fdc92b77915d5c7ab8fea751f48378f8b0080.

1) This did not fixed the issue
2) Long sleeping work items can cause IO requests to take as long as
   the longest work item

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ed43cdc..dbd6d72 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -951,10 +951,6 @@ int drbd_send_state(struct drbd_conf *mdev)
 	struct p_state p;
 	int ok = 0;
 
-	/* Grab state lock so we wont send state if we're in the middle
-	 * of a cluster wide state change on another thread */
-	drbd_state_lock(mdev);
-
 	mutex_lock(&mdev->tconn->data.mutex);
 
 	p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */
@@ -966,7 +962,6 @@ int drbd_send_state(struct drbd_conf *mdev)
 
 	mutex_unlock(&mdev->tconn->data.mutex);
 
-	drbd_state_unlock(mdev);
 	return ok;
 }
 
-- 
1.7.4.1


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

* [PATCH 067/118] drbd: Moving state related macros to drbd_state.h
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (65 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 066/118] drbd: Revert "Make sure we dont send state if a cluster wide state change is in progress" Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections Philipp Reisner
                   ` (52 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c625f59..df24541 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1603,58 +1603,6 @@ void drbd_bcast_ee(struct drbd_conf *, const char *, const int, const char *,
 		   const char *, const struct drbd_peer_request *);
 
 
-/**
- * DOC: DRBD State macros
- *
- * These macros are used to express state changes in easily readable form.
- *
- * The NS macros expand to a mask and a value, that can be bit ored onto the
- * current state as soon as the spinlock (req_lock) was taken.
- *
- * The _NS macros are used for state functions that get called with the
- * spinlock. These macros expand directly to the new state value.
- *
- * Besides the basic forms NS() and _NS() additional _?NS[23] are defined
- * to express state changes that affect more than one aspect of the state.
- *
- * E.g. NS2(conn, C_CONNECTED, peer, R_SECONDARY)
- * Means that the network connection was established and that the peer
- * is in secondary role.
- */
-#define role_MASK R_MASK
-#define peer_MASK R_MASK
-#define disk_MASK D_MASK
-#define pdsk_MASK D_MASK
-#define conn_MASK C_MASK
-#define susp_MASK 1
-#define user_isp_MASK 1
-#define aftr_isp_MASK 1
-#define susp_nod_MASK 1
-#define susp_fen_MASK 1
-
-#define NS(T, S) \
-	({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \
-	({ union drbd_state val; val.i = 0; val.T = (S); val; })
-#define NS2(T1, S1, T2, S2) \
-	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
-	  mask.T2 = T2##_MASK; mask; }), \
-	({ union drbd_state val; val.i = 0; val.T1 = (S1); \
-	  val.T2 = (S2); val; })
-#define NS3(T1, S1, T2, S2, T3, S3) \
-	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
-	  mask.T2 = T2##_MASK; mask.T3 = T3##_MASK; mask; }), \
-	({ union drbd_state val;  val.i = 0; val.T1 = (S1); \
-	  val.T2 = (S2); val.T3 = (S3); val; })
-
-#define _NS(D, T, S) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T = (S); __ns; })
-#define _NS2(D, T1, S1, T2, S2) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
-	__ns.T2 = (S2); __ns; })
-#define _NS3(D, T1, S1, T2, S2, T3, S3) \
-	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
-	__ns.T2 = (S2); __ns.T3 = (S3); __ns; })
-
 /*
  * inline helper functions
  *************************/
-- 
1.7.4.1


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

* [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (66 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 067/118] drbd: Moving state related macros to drbd_state.h Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 18:16   ` Joe Perches
  2011-08-25 15:08 ` [PATCH 069/118] drbd: Converted drbd_try_connect() from mdev to tconn Philipp Reisner
                   ` (51 subsequent siblings)
  119 siblings, 1 reply; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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 |   16 +++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index df24541..1ecde6f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -102,6 +102,15 @@ struct drbd_tconn;
 /* to shorten dev_warn(DEV, "msg"); and relatives statements */
 #define DEV (disk_to_dev(mdev->vdisk))
 
+extern void conn_printk(const char *level, struct drbd_tconn *tconn, const char *fmt, ...);
+#define conn_alert(TCONN, FMT, ARGS...)  conn_printk(KERN_ALERT, TCONN, FMT, ## ARGS)
+#define conn_crit(TCONN, FMT, ARGS...)   conn_printk(KERN_CRIT, TCONN, FMT, ## ARGS)
+#define conn_err(TCONN, FMT, ARGS...)    conn_printk(KERN_ERR, TCONN, FMT, ## ARGS)
+#define conn_warn(TCONN, FMT, ARGS...)   conn_printk(KERN_WARNING, TCONN, FMT, ## ARGS)
+#define conn_notice(TCONN, FMT, ARGS...) conn_printk(KERN_NOTICE, TCONN, FMT, ## ARGS)
+#define conn_info(TCONN, FMT, ARGS...)   conn_printk(KERN_INFO, TCONN, FMT, ## ARGS)
+#define conn_dbg(TCONN, FMT, ARGS...)    conn_printk(KERN_DEBUG, TCONN, FMT, ## ARGS)
+
 #define D_ASSERT(exp)	if (!(exp)) \
 	 dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__)
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index dbd6d72..0e2969d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -170,6 +170,18 @@ int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins)
 
 #endif
 
+/* printk functions for connections
+ */
+void conn_printk(const char *level, struct drbd_tconn *tconn, const char *fmt, ...)
+{
+	va_list args;
+
+	printk("%sd-con %s: ", level, tconn->name);
+	va_start(args, fmt);
+	vprintk(fmt, args);
+	va_end(args);
+}
+
 /**
  * DOC: The transfer log
  *
@@ -2217,12 +2229,14 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	struct drbd_conf *mdev;
 	struct gendisk *disk;
 	struct request_queue *q;
+	char conn_name[9]; /* drbd1234N */
 
 	/* GFP_KERNEL, we are outside of all write-out paths */
 	mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
 	if (!mdev)
 		return NULL;
-	mdev->tconn = drbd_new_tconn("dummy");
+	sprintf(conn_name, "drbd%d", minor);
+	mdev->tconn = drbd_new_tconn(conn_name);
 	if (!mdev->tconn)
 		goto out_no_tconn;
 
-- 
1.7.4.1


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

* [PATCH 069/118] drbd: Converted drbd_try_connect() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (67 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 070/118] drbd: Converted drbd_wait_for_connect() " Philipp Reisner
                   ` (50 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 78a05ec..c59858a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -572,7 +572,7 @@ static void drbd_setbufsize(struct socket *sock, unsigned int snd,
 	}
 }
 
-static struct socket *drbd_try_connect(struct drbd_conf *mdev)
+static struct socket *drbd_try_connect(struct drbd_tconn *tconn)
 {
 	const char *what;
 	struct socket *sock;
@@ -580,11 +580,11 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	int err;
 	int disconnect_on_error = 1;
 
-	if (!get_net_conf(mdev->tconn))
+	if (!get_net_conf(tconn))
 		return NULL;
 
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family,
+	err = sock_create_kern(((struct sockaddr *)tconn->net_conf->my_addr)->sa_family,
 		SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (err < 0) {
 		sock = NULL;
@@ -592,9 +592,9 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	}
 
 	sock->sk->sk_rcvtimeo =
-	sock->sk->sk_sndtimeo =  mdev->tconn->net_conf->try_connect_int*HZ;
-	drbd_setbufsize(sock, mdev->tconn->net_conf->sndbuf_size,
-			mdev->tconn->net_conf->rcvbuf_size);
+	sock->sk->sk_sndtimeo =  tconn->net_conf->try_connect_int*HZ;
+	drbd_setbufsize(sock, tconn->net_conf->sndbuf_size,
+			tconn->net_conf->rcvbuf_size);
 
        /* explicitly bind to the configured IP as source IP
 	*  for the outgoing connections.
@@ -603,9 +603,9 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	* Make sure to use 0 as port number, so linux selects
 	*  a free one dynamically.
 	*/
-	memcpy(&src_in6, mdev->tconn->net_conf->my_addr,
-	       min_t(int, mdev->tconn->net_conf->my_addr_len, sizeof(src_in6)));
-	if (((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family == AF_INET6)
+	memcpy(&src_in6, tconn->net_conf->my_addr,
+	       min_t(int, tconn->net_conf->my_addr_len, sizeof(src_in6)));
+	if (((struct sockaddr *)tconn->net_conf->my_addr)->sa_family == AF_INET6)
 		src_in6.sin6_port = 0;
 	else
 		((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */
@@ -613,7 +613,7 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	what = "bind before connect";
 	err = sock->ops->bind(sock,
 			      (struct sockaddr *) &src_in6,
-			      mdev->tconn->net_conf->my_addr_len);
+			      tconn->net_conf->my_addr_len);
 	if (err < 0)
 		goto out;
 
@@ -622,8 +622,8 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev)
 	disconnect_on_error = 0;
 	what = "connect";
 	err = sock->ops->connect(sock,
-				 (struct sockaddr *)mdev->tconn->net_conf->peer_addr,
-				 mdev->tconn->net_conf->peer_addr_len, 0);
+				 (struct sockaddr *)tconn->net_conf->peer_addr,
+				 tconn->net_conf->peer_addr_len, 0);
 
 out:
 	if (err < 0) {
@@ -641,12 +641,12 @@ out:
 			disconnect_on_error = 0;
 			break;
 		default:
-			dev_err(DEV, "%s failed, err = %d\n", what, err);
+			conn_err(tconn, "%s failed, err = %d\n", what, err);
 		}
 		if (disconnect_on_error)
-			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
 	}
-	put_net_conf(mdev->tconn);
+	put_net_conf(tconn);
 	return sock;
 }
 
@@ -774,7 +774,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 	do {
 		for (try = 0;;) {
 			/* 3 tries, this should take less than a second! */
-			s = drbd_try_connect(mdev);
+			s = drbd_try_connect(mdev->tconn);
 			if (s || ++try >= 3)
 				break;
 			/* give the other side time to call bind() & listen() */
-- 
1.7.4.1


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

* [PATCH 070/118] drbd: Converted drbd_wait_for_connect() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (68 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 069/118] drbd: Converted drbd_try_connect() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 071/118] drbd: Started to separated connection flags (tconn) from block device flags (mdev) Philipp Reisner
                   ` (49 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index c59858a..83066a3 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -447,8 +447,7 @@ void drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
 
 /* see also kernel_accept; which is only present since 2.6.18.
  * also we want to log which part of it failed, exactly */
-static int drbd_accept(struct drbd_conf *mdev, const char **what,
-		struct socket *sock, struct socket **newsock)
+static int drbd_accept(const char **what, struct socket *sock, struct socket **newsock)
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
@@ -650,51 +649,51 @@ out:
 	return sock;
 }
 
-static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev)
+static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn)
 {
 	int timeo, err;
 	struct socket *s_estab = NULL, *s_listen;
 	const char *what;
 
-	if (!get_net_conf(mdev->tconn))
+	if (!get_net_conf(tconn))
 		return NULL;
 
 	what = "sock_create_kern";
-	err = sock_create_kern(((struct sockaddr *)mdev->tconn->net_conf->my_addr)->sa_family,
+	err = sock_create_kern(((struct sockaddr *)tconn->net_conf->my_addr)->sa_family,
 		SOCK_STREAM, IPPROTO_TCP, &s_listen);
 	if (err) {
 		s_listen = NULL;
 		goto out;
 	}
 
-	timeo = mdev->tconn->net_conf->try_connect_int * HZ;
+	timeo = tconn->net_conf->try_connect_int * HZ;
 	timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */
 
 	s_listen->sk->sk_reuse    = 1; /* SO_REUSEADDR */
 	s_listen->sk->sk_rcvtimeo = timeo;
 	s_listen->sk->sk_sndtimeo = timeo;
-	drbd_setbufsize(s_listen, mdev->tconn->net_conf->sndbuf_size,
-			mdev->tconn->net_conf->rcvbuf_size);
+	drbd_setbufsize(s_listen, tconn->net_conf->sndbuf_size,
+			tconn->net_conf->rcvbuf_size);
 
 	what = "bind before listen";
 	err = s_listen->ops->bind(s_listen,
-			      (struct sockaddr *) mdev->tconn->net_conf->my_addr,
-			      mdev->tconn->net_conf->my_addr_len);
+			      (struct sockaddr *) tconn->net_conf->my_addr,
+			      tconn->net_conf->my_addr_len);
 	if (err < 0)
 		goto out;
 
-	err = drbd_accept(mdev, &what, s_listen, &s_estab);
+	err = drbd_accept(&what, s_listen, &s_estab);
 
 out:
 	if (s_listen)
 		sock_release(s_listen);
 	if (err < 0) {
 		if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) {
-			dev_err(DEV, "%s failed, err = %d\n", what, err);
-			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			conn_err(tconn, "%s failed, err = %d\n", what, err);
+			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
 		}
 	}
-	put_net_conf(mdev->tconn);
+	put_net_conf(tconn);
 
 	return s_estab;
 }
@@ -805,7 +804,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 		}
 
 retry:
-		s = drbd_wait_for_connect(mdev);
+		s = drbd_wait_for_connect(mdev->tconn);
 		if (s) {
 			try = drbd_recv_fp(mdev, s);
 			drbd_socket_okay(mdev, &sock);
-- 
1.7.4.1


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

* [PATCH 071/118] drbd: Started to separated connection flags (tconn) from block device flags (mdev)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (69 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 070/118] drbd: Converted drbd_wait_for_connect() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 072/118] drbd: Moved DISCARD_CONCURRENT to the per connection (tconn) flags Philipp Reisner
                   ` (48 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1ecde6f..b325b0a 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -753,7 +753,7 @@ enum {
 #define EE_WAS_ERROR           (1<<__EE_WAS_ERROR)
 #define EE_HAS_DIGEST          (1<<__EE_HAS_DIGEST)
 
-/* global flag bits */
+/* flag bits per mdev */
 enum {
 	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
@@ -781,8 +781,6 @@ enum {
 	GO_DISKLESS,		/* Disk is being detached, on io-error or admin request. */
 	WAS_IO_ERROR,		/* Local disk failed returned IO error */
 	RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
-	NET_CONGESTED,		/* The data socket is congested */
-
 	CONFIG_PENDING,		/* serialization of (re)configuration requests.
 				 * if set, also prevents the device from dying */
 	DEVICE_DYING,		/* device became unconfigured,
@@ -909,10 +907,16 @@ struct fifo_buffer {
 	unsigned int size;
 };
 
+/* flag bits per tconn */
+enum {
+	NET_CONGESTED,		/* The data socket is congested */
+};
+
 struct drbd_tconn {			/* is a resource from the config file */
 	char *name;			/* Resource name */
 	struct list_head all_tconn;	/* List of all drbd_tconn, prot by global_state_lock */
 	struct drbd_conf *volume0;	/* TODO: Remove me again */
+	unsigned long flags;
 
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
 	atomic_t net_cnt;		/* Users of net_conf */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0e2969d..45b8f67 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1370,7 +1370,7 @@ static void drbd_update_congested(struct drbd_conf *mdev)
 {
 	struct sock *sk = mdev->tconn->data.socket->sk;
 	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
-		set_bit(NET_CONGESTED, &mdev->flags);
+		set_bit(NET_CONGESTED, &mdev->tconn->flags);
 }
 
 /* The idea of sendpage seems to be to put some kind of reference
@@ -1443,7 +1443,7 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
 		offset += sent;
 	} while (len > 0 /* THINK && mdev->cstate >= C_CONNECTED*/);
 	set_fs(oldfs);
-	clear_bit(NET_CONGESTED, &mdev->flags);
+	clear_bit(NET_CONGESTED, &mdev->tconn->flags);
 
 	ok = (len == 0);
 	if (likely(ok))
@@ -1706,7 +1706,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 	} while (sent < size);
 
 	if (sock == mdev->tconn->data.socket)
-		clear_bit(NET_CONGESTED, &mdev->flags);
+		clear_bit(NET_CONGESTED, &mdev->tconn->flags);
 
 	if (rv <= 0) {
 		if (rv != -EAGAIN) {
@@ -2173,7 +2173,7 @@ static int drbd_congested(void *congested_data, int bdi_bits)
 			reason = 'b';
 	}
 
-	if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &mdev->flags)) {
+	if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &mdev->tconn->flags)) {
 		r |= (1 << BDI_async_congested);
 		reason = reason == 'b' ? 'a' : 'n';
 	}
-- 
1.7.4.1


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

* [PATCH 072/118] drbd: Moved DISCARD_CONCURRENT to the per connection (tconn) flags
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (70 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 071/118] drbd: Started to separated connection flags (tconn) from block device flags (mdev) Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 073/118] drbd: Moved SEND_PING " Philipp Reisner
                   ` (47 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index b325b0a..a88bf7c 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -762,7 +762,6 @@ enum {
 	UNPLUG_QUEUED,		/* only relevant with kernel 2.4 */
 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
 	MD_DIRTY,		/* current uuids and flags not yet on disk */
-	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
 	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
 	CLUSTER_ST_CHANGE,	/* Cluster wide state change going on... */
 	CL_ST_CHG_SUCCESS,
@@ -910,6 +909,7 @@ struct fifo_buffer {
 /* flag bits per tconn */
 enum {
 	NET_CONGESTED,		/* The data socket is congested */
+	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
 };
 
 struct drbd_tconn {			/* is a resource from the config file */
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index e30d52b..fda399a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1637,7 +1637,7 @@ void resync_after_online_grow(struct drbd_conf *mdev)
 	if (mdev->state.role != mdev->state.peer)
 		iass = (mdev->state.role == R_PRIMARY);
 	else
-		iass = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+		iass = test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
 
 	if (iass)
 		drbd_start_resync(mdev, C_SYNC_SOURCE);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 83066a3..cb45a3c 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -762,7 +762,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 	if (drbd_request_state(mdev, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
 		return -2;
 
-	clear_bit(DISCARD_CONCURRENT, &mdev->flags);
+	clear_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
 	mdev->tconn->agreed_pro_version = 99;
 	/* agreed_pro_version must be smaller than 100 so we send the old
 	   header (h80) in the first packet and in the handshake packet. */
@@ -823,7 +823,7 @@ retry:
 					sock_release(msock);
 				}
 				msock = s;
-				set_bit(DISCARD_CONCURRENT, &mdev->flags);
+				set_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
 				break;
 			default:
 				dev_warn(DEV, "Error receiving initial packet\n");
@@ -1783,7 +1783,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 		/* don't get the req_lock yet,
 		 * we may sleep in drbd_wait_peer_seq */
 		const int size = peer_req->i.size;
-		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
 		DEFINE_WAIT(wait);
 		int first;
 
@@ -2243,7 +2243,7 @@ static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
 		     "Using discard-least-changes instead\n");
 	case ASB_DISCARD_ZERO_CHG:
 		if (ch_peer == 0 && ch_self == 0) {
-			rv = test_bit(DISCARD_CONCURRENT, &mdev->flags)
+			rv = test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags)
 				? -1 : 1;
 			break;
 		} else {
@@ -2259,7 +2259,7 @@ static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
 			rv =  1;
 		else /* ( ch_self == ch_peer ) */
 		     /* Well, then use something else. */
-			rv = test_bit(DISCARD_CONCURRENT, &mdev->flags)
+			rv = test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags)
 				? -1 : 1;
 		break;
 	case ASB_DISCARD_LOCAL:
@@ -2472,7 +2472,7 @@ static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
 		case 1: /*  self_pri && !peer_pri */ return 1;
 		case 2: /* !self_pri &&  peer_pri */ return -1;
 		case 3: /*  self_pri &&  peer_pri */
-			dc = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+			dc = test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
 			return dc ? -1 : 1;
 		}
 	}
@@ -3213,7 +3213,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
 	mask.i = be32_to_cpu(p->mask);
 	val.i = be32_to_cpu(p->val);
 
-	if (test_bit(DISCARD_CONCURRENT, &mdev->flags) &&
+	if (test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags) &&
 	    test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) {
 		drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG);
 		return true;
-- 
1.7.4.1


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

* [PATCH 073/118] drbd: Moved SEND_PING to the per connection (tconn) flags
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (71 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 072/118] drbd: Moved DISCARD_CONCURRENT to the per connection (tconn) flags Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 074/118] drbd: Moved SIGNAL_ASENDER " Philipp Reisner
                   ` (46 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index a88bf7c..9024bc6 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -757,7 +757,6 @@ enum {
 enum {
 	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
-	SEND_PING,		/* whether asender should send a ping asap */
 
 	UNPLUG_QUEUED,		/* only relevant with kernel 2.4 */
 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
@@ -910,6 +909,7 @@ struct fifo_buffer {
 enum {
 	NET_CONGESTED,		/* The data socket is congested */
 	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
+	SEND_PING,		/* whether asender should send a ping asap */
 };
 
 struct drbd_tconn {			/* is a resource from the config file */
@@ -1866,7 +1866,7 @@ static inline void wake_asender(struct drbd_conf *mdev)
 
 static inline void request_ping(struct drbd_conf *mdev)
 {
-	set_bit(SEND_PING, &mdev->flags);
+	set_bit(SEND_PING, &mdev->tconn->flags);
 	wake_asender(mdev);
 }
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cb45a3c..4b1d19d 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4568,7 +4568,7 @@ int drbd_asender(struct drbd_thread *thi)
 
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev, thi);
-		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
+		if (test_and_clear_bit(SEND_PING, &mdev->tconn->flags)) {
 			if (!drbd_send_ping(mdev)) {
 				dev_err(DEV, "drbd_send_ping has failed\n");
 				goto reconnect;
@@ -4639,7 +4639,7 @@ int drbd_asender(struct drbd_thread *thi)
 				dev_err(DEV, "PingAck did not arrive in time.\n");
 				goto reconnect;
 			}
-			set_bit(SEND_PING, &mdev->flags);
+			set_bit(SEND_PING, &mdev->tconn->flags);
 			continue;
 		} else if (rv == -EINTR) {
 			continue;
-- 
1.7.4.1


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

* [PATCH 074/118] drbd: Moved SIGNAL_ASENDER to the per connection (tconn) flags
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (72 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 073/118] drbd: Moved SEND_PING " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 075/118] drbd: Converted wake_asender() and request_ping() from mdev to tconn Philipp Reisner
                   ` (45 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9024bc6..1c43975 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -756,8 +756,6 @@ enum {
 /* flag bits per mdev */
 enum {
 	CREATE_BARRIER,		/* next P_DATA is preceded by a P_BARRIER */
-	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
-
 	UNPLUG_QUEUED,		/* only relevant with kernel 2.4 */
 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
 	MD_DIRTY,		/* current uuids and flags not yet on disk */
@@ -910,6 +908,7 @@ enum {
 	NET_CONGESTED,		/* The data socket is congested */
 	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
 	SEND_PING,		/* whether asender should send a ping asap */
+	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
 };
 
 struct drbd_tconn {			/* is a resource from the config file */
@@ -1860,7 +1859,7 @@ drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
 
 static inline void wake_asender(struct drbd_conf *mdev)
 {
-	if (test_bit(SIGNAL_ASENDER, &mdev->flags))
+	if (test_bit(SIGNAL_ASENDER, &mdev->tconn->flags))
 		force_sig(DRBD_SIG, mdev->tconn->asender.task);
 }
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 4b1d19d..5f44b43 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4584,12 +4584,12 @@ int drbd_asender(struct drbd_thread *thi)
 			3 < atomic_read(&mdev->unacked_cnt))
 			drbd_tcp_cork(mdev->tconn->meta.socket);
 		while (1) {
-			clear_bit(SIGNAL_ASENDER, &mdev->flags);
+			clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
 			flush_signals(current);
 			if (!drbd_process_done_ee(mdev))
 				goto reconnect;
 			/* to avoid race with newly queued ACKs */
-			set_bit(SIGNAL_ASENDER, &mdev->flags);
+			set_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
 			spin_lock_irq(&mdev->tconn->req_lock);
 			empty = list_empty(&mdev->done_ee);
 			spin_unlock_irq(&mdev->tconn->req_lock);
@@ -4609,7 +4609,7 @@ int drbd_asender(struct drbd_thread *thi)
 
 		rv = drbd_recv_short(mdev, mdev->tconn->meta.socket,
 				     buf, expect-received, 0);
-		clear_bit(SIGNAL_ASENDER, &mdev->flags);
+		clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
 
 		flush_signals(current);
 
@@ -4692,7 +4692,7 @@ disconnect:
 		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
 		drbd_md_sync(mdev);
 	}
-	clear_bit(SIGNAL_ASENDER, &mdev->flags);
+	clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
 
 	D_ASSERT(mdev->state.conn < C_CONNECTED);
 	dev_info(DEV, "asender terminated\n");
-- 
1.7.4.1


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

* [PATCH 075/118] drbd: Converted wake_asender() and request_ping() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (73 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 074/118] drbd: Moved SIGNAL_ASENDER " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 076/118] drbd: Converted helper functions for drbd_send() " Philipp Reisner
                   ` (44 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1c43975..e8c2c2a 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1857,16 +1857,16 @@ drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
 	spin_unlock_irqrestore(&q->q_lock, flags);
 }
 
-static inline void wake_asender(struct drbd_conf *mdev)
+static inline void wake_asender(struct drbd_tconn *tconn)
 {
-	if (test_bit(SIGNAL_ASENDER, &mdev->tconn->flags))
-		force_sig(DRBD_SIG, mdev->tconn->asender.task);
+	if (test_bit(SIGNAL_ASENDER, &tconn->flags))
+		force_sig(DRBD_SIG, tconn->asender.task);
 }
 
-static inline void request_ping(struct drbd_conf *mdev)
+static inline void request_ping(struct drbd_tconn *tconn)
 {
-	set_bit(SEND_PING, &mdev->tconn->flags);
-	wake_asender(mdev);
+	set_bit(SEND_PING, &tconn->flags);
+	wake_asender(tconn);
 }
 
 static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 45b8f67..4c31410 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1360,7 +1360,7 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *
 	if (!drop_it) {
 		dev_err(DEV, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
 		       current->comm, current->pid, mdev->tconn->ko_count);
-		request_ping(mdev);
+		request_ping(mdev->tconn);
 	}
 
 	return drop_it; /* && (mdev->state == R_PRIMARY) */;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index fda399a..df36a57 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -318,7 +318,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 	enum drbd_disk_state nps;
 
 	if (new_role == R_PRIMARY)
-		request_ping(mdev); /* Detect a dead peer ASAP */
+		request_ping(mdev->tconn); /* Detect a dead peer ASAP */
 
 	mutex_lock(&mdev->state_mutex);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 5f44b43..409b8c8 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1868,7 +1868,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
 				 * but I don't like the receiver using the msock */
 
 				put_ldev(mdev);
-				wake_asender(mdev);
+				wake_asender(mdev->tconn);
 				finish_wait(&mdev->misc_wait, &wait);
 				return true;
 			}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index a705979..5be179b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -145,7 +145,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
 	if (do_al_complete_io)
 		drbd_al_complete_io(mdev, e_sector);
 
-	wake_asender(mdev);
+	wake_asender(mdev->tconn);
 	put_ldev(mdev);
 }
 
@@ -728,7 +728,7 @@ static int w_resync_finished(struct drbd_conf *mdev, struct drbd_work *w, int ca
 static void ping_peer(struct drbd_conf *mdev)
 {
 	clear_bit(GOT_PING_ACK, &mdev->flags);
-	request_ping(mdev);
+	request_ping(mdev->tconn);
 	wait_event(mdev->misc_wait,
 		   test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
 }
-- 
1.7.4.1


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

* [PATCH 076/118] drbd: Converted helper functions for drbd_send() to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (74 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 075/118] drbd: Converted wake_asender() and request_ping() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 077/118] drbd: Converted drbd_send() from mdev " Philipp Reisner
                   ` (43 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

* drbd_update_congested()
* we_should_drop_the_connection()

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 4c31410..1f9eac0 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1343,34 +1343,34 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size)
  * returns false if we should retry,
  * true if we think connection is dead
  */
-static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *sock)
+static int we_should_drop_the_connection(struct drbd_tconn *tconn, struct socket *sock)
 {
 	int drop_it;
 	/* long elapsed = (long)(jiffies - mdev->last_received); */
 
-	drop_it =   mdev->tconn->meta.socket == sock
-		|| !mdev->tconn->asender.task
-		|| get_t_state(&mdev->tconn->asender) != RUNNING
-		|| mdev->state.conn < C_CONNECTED;
+	drop_it =   tconn->meta.socket == sock
+		|| !tconn->asender.task
+		|| get_t_state(&tconn->asender) != RUNNING
+		|| tconn->volume0->state.conn < C_CONNECTED;
 
 	if (drop_it)
 		return true;
 
-	drop_it = !--mdev->tconn->ko_count;
+	drop_it = !--tconn->ko_count;
 	if (!drop_it) {
-		dev_err(DEV, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
-		       current->comm, current->pid, mdev->tconn->ko_count);
-		request_ping(mdev->tconn);
+		conn_err(tconn, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
+			 current->comm, current->pid, tconn->ko_count);
+		request_ping(tconn);
 	}
 
 	return drop_it; /* && (mdev->state == R_PRIMARY) */;
 }
 
-static void drbd_update_congested(struct drbd_conf *mdev)
+static void drbd_update_congested(struct drbd_tconn *tconn)
 {
-	struct sock *sk = mdev->tconn->data.socket->sk;
+	struct sock *sk = tconn->data.socket->sk;
 	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
-		set_bit(NET_CONGESTED, &mdev->tconn->flags);
+		set_bit(NET_CONGESTED, &tconn->flags);
 }
 
 /* The idea of sendpage seems to be to put some kind of reference
@@ -1421,14 +1421,14 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
 		return _drbd_no_send_page(mdev, page, offset, size, msg_flags);
 
 	msg_flags |= MSG_NOSIGNAL;
-	drbd_update_congested(mdev);
+	drbd_update_congested(mdev->tconn);
 	set_fs(KERNEL_DS);
 	do {
 		sent = mdev->tconn->data.socket->ops->sendpage(mdev->tconn->data.socket, page,
 							offset, len,
 							msg_flags);
 		if (sent == -EAGAIN) {
-			if (we_should_drop_the_connection(mdev,
+			if (we_should_drop_the_connection(mdev->tconn,
 							  mdev->tconn->data.socket))
 				break;
 			else
@@ -1674,7 +1674,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 
 	if (sock == mdev->tconn->data.socket) {
 		mdev->tconn->ko_count = mdev->tconn->net_conf->ko_count;
-		drbd_update_congested(mdev);
+		drbd_update_congested(mdev->tconn);
 	}
 	do {
 		/* STRANGE
@@ -1688,7 +1688,7 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
  */
 		rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
 		if (rv == -EAGAIN) {
-			if (we_should_drop_the_connection(mdev, sock))
+			if (we_should_drop_the_connection(mdev->tconn, sock))
 				break;
 			else
 				continue;
-- 
1.7.4.1


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

* [PATCH 077/118] drbd: Converted drbd_send() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (75 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 076/118] drbd: Converted helper functions for drbd_send() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 078/118] drbd: Converted drbd_send_fp() " Philipp Reisner
                   ` (42 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index e8c2c2a..1f590b9 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1158,8 +1158,8 @@ extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 extern void tl_clear(struct drbd_conf *mdev);
 extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *);
 extern void drbd_free_sock(struct drbd_conf *mdev);
-extern int drbd_send(struct drbd_conf *mdev, struct socket *sock,
-			void *buf, size_t size, unsigned msg_flags);
+extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
+		     void *buf, size_t size, unsigned msg_flags);
 extern int drbd_send_protocol(struct drbd_conf *mdev);
 extern int drbd_send_uuids(struct drbd_conf *mdev);
 extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 1f9eac0..357397e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -702,7 +702,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
 
 	prepare_header(mdev, h, cmd, size - sizeof(struct p_header));
 
-	sent = drbd_send(mdev, sock, h, size, msg_flags);
+	sent = drbd_send(mdev->tconn, sock, h, size, msg_flags);
 
 	ok = (sent == size);
 	if (!ok && !signal_pending(current))
@@ -752,9 +752,9 @@ int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd, char *data,
 		return 0;
 
 	ok = (sizeof(h) ==
-		drbd_send(mdev, mdev->tconn->data.socket, &h, sizeof(h), 0));
+		drbd_send(mdev->tconn, mdev->tconn->data.socket, &h, sizeof(h), 0));
 	ok = ok && (size ==
-		drbd_send(mdev, mdev->tconn->data.socket, data, size, 0));
+		drbd_send(mdev->tconn, mdev->tconn->data.socket, data, size, 0));
 
 	drbd_put_data_sock(mdev);
 
@@ -1318,8 +1318,8 @@ int drbd_send_drequest_csum(struct drbd_conf *mdev, sector_t sector, int size,
 
 	mutex_lock(&mdev->tconn->data.mutex);
 
-	ok = (sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), 0));
-	ok = ok && (digest_size == drbd_send(mdev, mdev->tconn->data.socket, digest, digest_size, 0));
+	ok = (sizeof(p) == drbd_send(mdev->tconn, mdev->tconn->data.socket, &p, sizeof(p), 0));
+	ok = ok && (digest_size == drbd_send(mdev->tconn, mdev->tconn->data.socket, digest, digest_size, 0));
 
 	mutex_unlock(&mdev->tconn->data.mutex);
 
@@ -1397,7 +1397,7 @@ static void drbd_update_congested(struct drbd_tconn *tconn)
 static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
 		   int offset, size_t size, unsigned msg_flags)
 {
-	int sent = drbd_send(mdev, mdev->tconn->data.socket, kmap(page) + offset, size, msg_flags);
+	int sent = drbd_send(mdev->tconn, mdev->tconn->data.socket, kmap(page) + offset, size, msg_flags);
 	kunmap(page);
 	if (sent == size)
 		mdev->send_cnt += size>>9;
@@ -1538,11 +1538,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	p.dp_flags = cpu_to_be32(dp_flags);
 	set_bit(UNPLUG_REMOTE, &mdev->flags);
 	ok = (sizeof(p) ==
-		drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
+		drbd_send(mdev->tconn, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0));
 	if (ok && dgs) {
 		dgb = mdev->tconn->int_dig_out;
 		drbd_csum_bio(mdev, mdev->tconn->integrity_w_tfm, req->master_bio, dgb);
-		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
+		ok = dgs == drbd_send(mdev->tconn, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok) {
 		/* For protocol A, we have to memcpy the payload into
@@ -1611,11 +1611,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	if (!drbd_get_data_sock(mdev))
 		return 0;
 
-	ok = sizeof(p) == drbd_send(mdev, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
+	ok = sizeof(p) == drbd_send(mdev->tconn, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
 	if (ok && dgs) {
 		dgb = mdev->tconn->int_dig_out;
 		drbd_csum_ee(mdev, mdev->tconn->integrity_w_tfm, peer_req, dgb);
-		ok = dgs == drbd_send(mdev, mdev->tconn->data.socket, dgb, dgs, 0);
+		ok = dgs == drbd_send(mdev->tconn, mdev->tconn->data.socket, dgb, dgs, 0);
 	}
 	if (ok)
 		ok = _drbd_send_zc_ee(mdev, peer_req);
@@ -1651,7 +1651,7 @@ int drbd_send_oos(struct drbd_conf *mdev, struct drbd_request *req)
 /*
  * you must have down()ed the appropriate [m]sock_mutex elsewhere!
  */
-int drbd_send(struct drbd_conf *mdev, struct socket *sock,
+int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
 	      void *buf, size_t size, unsigned msg_flags)
 {
 	struct kvec iov;
@@ -1672,9 +1672,9 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 	msg.msg_controllen = 0;
 	msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
 
-	if (sock == mdev->tconn->data.socket) {
-		mdev->tconn->ko_count = mdev->tconn->net_conf->ko_count;
-		drbd_update_congested(mdev->tconn);
+	if (sock == tconn->data.socket) {
+		tconn->ko_count = tconn->net_conf->ko_count;
+		drbd_update_congested(tconn);
 	}
 	do {
 		/* STRANGE
@@ -1688,12 +1688,11 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
  */
 		rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
 		if (rv == -EAGAIN) {
-			if (we_should_drop_the_connection(mdev->tconn, sock))
+			if (we_should_drop_the_connection(tconn, sock))
 				break;
 			else
 				continue;
 		}
-		D_ASSERT(rv != 0);
 		if (rv == -EINTR) {
 			flush_signals(current);
 			rv = 0;
@@ -1705,17 +1704,17 @@ int drbd_send(struct drbd_conf *mdev, struct socket *sock,
 		iov.iov_len  -= rv;
 	} while (sent < size);
 
-	if (sock == mdev->tconn->data.socket)
-		clear_bit(NET_CONGESTED, &mdev->tconn->flags);
+	if (sock == tconn->data.socket)
+		clear_bit(NET_CONGESTED, &tconn->flags);
 
 	if (rv <= 0) {
 		if (rv != -EAGAIN) {
-			dev_err(DEV, "%s_sendmsg returned %d\n",
-			    sock == mdev->tconn->meta.socket ? "msock" : "sock",
-			    rv);
-			drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE));
+			conn_err(tconn, "%s_sendmsg returned %d\n",
+				 sock == tconn->meta.socket ? "msock" : "sock",
+				 rv);
+			drbd_force_state(tconn->volume0, NS(conn, C_BROKEN_PIPE));
 		} else
-			drbd_force_state(mdev, NS(conn, C_TIMEOUT));
+			drbd_force_state(tconn->volume0, NS(conn, C_TIMEOUT));
 	}
 
 	return sent;
-- 
1.7.4.1


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

* [PATCH 078/118] drbd: Converted drbd_send_fp() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (76 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 077/118] drbd: Converted drbd_send() from mdev " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 079/118] drbd: Removed unused mdev argument from drbd_recv_short() and drbd_socket_okay() Philipp Reisner
                   ` (41 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1f590b9..615405d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1167,9 +1167,9 @@ extern int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev);
 extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags);
 extern int _drbd_send_state(struct drbd_conf *mdev);
 extern int drbd_send_state(struct drbd_conf *mdev);
-extern int _drbd_send_cmd(struct drbd_conf *mdev, struct 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 socket *sock,
+			  enum drbd_packet cmd, struct p_header *h, size_t size,
+			  unsigned msg_flags);
 #define USE_DATA_SOCKET 1
 #define USE_META_SOCKET 0
 extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
@@ -1869,6 +1869,13 @@ static inline void request_ping(struct drbd_tconn *tconn)
 	wake_asender(tconn);
 }
 
+static inline int _drbd_send_cmd(struct drbd_conf *mdev, struct 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_short_cmd(struct drbd_conf *mdev,
 				      enum drbd_packet cmd)
 {
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 357397e..544171a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -663,51 +663,50 @@ void drbd_thread_current_set_cpu(struct drbd_conf *mdev, struct drbd_thread *thi
 }
 #endif
 
-static void prepare_header80(struct drbd_conf *mdev, struct p_header80 *h,
-			     enum drbd_packet cmd, int size)
+static void 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);
 }
 
-static void prepare_header95(struct drbd_conf *mdev, struct p_header95 *h,
-			     enum drbd_packet cmd, int size)
+static void 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(mdev->vnr << 24 | size);
+	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)
+{
+	if (tconn->agreed_pro_version >= 100 || size > DRBD_MAX_SIZE_H80_PACKET)
+		prepare_header95(&h->h95, cmd, size, vnr);
+	else
+		prepare_header80(&h->h80, cmd, size);
 }
 
 static void prepare_header(struct drbd_conf *mdev, struct p_header *h,
 			   enum drbd_packet cmd, int size)
 {
-	if (mdev->tconn->agreed_pro_version >= 100 || size > DRBD_MAX_SIZE_H80_PACKET)
-		prepare_header95(mdev, &h->h95, cmd, size);
-	else
-		prepare_header80(mdev, &h->h80, cmd, size);
+	_prepare_header(mdev->tconn, mdev->vnr, h, cmd, size);
 }
 
 /* the appropriate socket mutex must be held already */
-int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
+int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct socket *sock,
 		   enum drbd_packet cmd, struct p_header *h, size_t size,
 		   unsigned msg_flags)
 {
 	int sent, ok;
 
-	if (!expect(h))
-		return false;
-	if (!expect(size))
-		return false;
-
-	prepare_header(mdev, h, cmd, size - sizeof(struct p_header));
+	_prepare_header(tconn, vnr, h, cmd, size - sizeof(struct p_header));
 
-	sent = drbd_send(mdev->tconn, sock, h, size, msg_flags);
+	sent = drbd_send(tconn, sock, h, size, msg_flags);
 
 	ok = (sent == size);
 	if (!ok && !signal_pending(current))
-		dev_warn(DEV, "short sent %s size=%d sent=%d\n",
-		    cmdname(cmd), (int)size, sent);
+		conn_warn(tconn, "short sent %s size=%d sent=%d\n",
+			  cmdname(cmd), (int)size, sent);
 	return ok;
 }
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 409b8c8..55538d7 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -698,16 +698,14 @@ out:
 	return s_estab;
 }
 
-static int drbd_send_fp(struct drbd_conf *mdev, struct socket *sock,
-			enum drbd_packet cmd)
+static int drbd_send_fp(struct drbd_tconn *tconn, struct socket *sock, enum drbd_packet cmd)
 {
-	struct p_header *h = &mdev->tconn->data.sbuf.header;
+	struct p_header *h = &tconn->data.sbuf.header;
 
-	return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0);
+	return _conn_send_cmd(tconn, 0, sock, cmd, h, sizeof(*h), 0);
 }
 
-static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev,
-				     struct socket *sock)
+static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock)
 {
 	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
 	int rr;
@@ -782,11 +780,11 @@ static int drbd_connect(struct drbd_conf *mdev)
 
 		if (s) {
 			if (!sock) {
-				drbd_send_fp(mdev, s, P_HAND_SHAKE_S);
+				drbd_send_fp(mdev->tconn, s, P_HAND_SHAKE_S);
 				sock = s;
 				s = NULL;
 			} else if (!msock) {
-				drbd_send_fp(mdev, s, P_HAND_SHAKE_M);
+				drbd_send_fp(mdev->tconn, s, P_HAND_SHAKE_M);
 				msock = s;
 				s = NULL;
 			} else {
-- 
1.7.4.1


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

* [PATCH 079/118] drbd: Removed unused mdev argument from drbd_recv_short() and drbd_socket_okay()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (77 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 078/118] drbd: Converted drbd_send_fp() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 080/118] drbd: Converted drbd_recv_fp() from mdev to tconn Philipp Reisner
                   ` (40 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 55538d7..2e1972e 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -476,8 +476,7 @@ out:
 	return err;
 }
 
-static int drbd_recv_short(struct drbd_conf *mdev, struct socket *sock,
-		    void *buf, size_t size, int flags)
+static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flags)
 {
 	mm_segment_t oldfs;
 	struct kvec iov = {
@@ -710,7 +709,7 @@ static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock
 	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
 	int rr;
 
-	rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0);
+	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);
@@ -720,10 +719,9 @@ static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock
 
 /**
  * drbd_socket_okay() - Free the socket if its connection is not okay
- * @mdev:	DRBD device.
  * @sock:	pointer to the pointer to the socket.
  */
-static int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock)
+static int drbd_socket_okay(struct socket **sock)
 {
 	int rr;
 	char tb[4];
@@ -731,7 +729,7 @@ static int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock)
 	if (!*sock)
 		return false;
 
-	rr = drbd_recv_short(mdev, *sock, tb, 4, MSG_DONTWAIT | MSG_PEEK);
+	rr = drbd_recv_short(*sock, tb, 4, MSG_DONTWAIT | MSG_PEEK);
 
 	if (rr > 0 || rr == -EAGAIN) {
 		return true;
@@ -795,8 +793,8 @@ static int drbd_connect(struct drbd_conf *mdev)
 
 		if (sock && msock) {
 			schedule_timeout_interruptible(mdev->tconn->net_conf->ping_timeo*HZ/10);
-			ok = drbd_socket_okay(mdev, &sock);
-			ok = drbd_socket_okay(mdev, &msock) && ok;
+			ok = drbd_socket_okay(&sock);
+			ok = drbd_socket_okay(&msock) && ok;
 			if (ok)
 				break;
 		}
@@ -805,8 +803,8 @@ retry:
 		s = drbd_wait_for_connect(mdev->tconn);
 		if (s) {
 			try = drbd_recv_fp(mdev, s);
-			drbd_socket_okay(mdev, &sock);
-			drbd_socket_okay(mdev, &msock);
+			drbd_socket_okay(&sock);
+			drbd_socket_okay(&msock);
 			switch (try) {
 			case P_HAND_SHAKE_S:
 				if (sock) {
@@ -841,8 +839,8 @@ retry:
 		}
 
 		if (sock && msock) {
-			ok = drbd_socket_okay(mdev, &sock);
-			ok = drbd_socket_okay(mdev, &msock) && ok;
+			ok = drbd_socket_okay(&sock);
+			ok = drbd_socket_okay(&msock) && ok;
 			if (ok)
 				break;
 		}
@@ -4605,8 +4603,7 @@ int drbd_asender(struct drbd_thread *thi)
 		if (signal_pending(current))
 			continue;
 
-		rv = drbd_recv_short(mdev, mdev->tconn->meta.socket,
-				     buf, expect-received, 0);
+		rv = drbd_recv_short(mdev->tconn->meta.socket, buf, expect-received, 0);
 		clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
 
 		flush_signals(current);
-- 
1.7.4.1


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

* [PATCH 080/118] drbd: Converted drbd_recv_fp() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (78 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 079/118] drbd: Removed unused mdev argument from drbd_recv_short() and drbd_socket_okay() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 081/118] drbd: Converted drbd_send_handshake() " Philipp Reisner
                   ` (39 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 2e1972e..080c91b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -704,9 +704,9 @@ static int drbd_send_fp(struct drbd_tconn *tconn, struct socket *sock, enum drbd
 	return _conn_send_cmd(tconn, 0, sock, cmd, h, sizeof(*h), 0);
 }
 
-static enum drbd_packet drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock)
+static enum drbd_packet drbd_recv_fp(struct drbd_tconn *tconn, struct socket *sock)
 {
-	struct p_header80 *h = &mdev->tconn->data.rbuf.header.h80;
+	struct p_header80 *h = &tconn->data.rbuf.header.h80;
 	int rr;
 
 	rr = drbd_recv_short(sock, h, sizeof(*h), 0);
@@ -802,7 +802,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 retry:
 		s = drbd_wait_for_connect(mdev->tconn);
 		if (s) {
-			try = drbd_recv_fp(mdev, s);
+			try = drbd_recv_fp(mdev->tconn, s);
 			drbd_socket_okay(&sock);
 			drbd_socket_okay(&msock);
 			switch (try) {
-- 
1.7.4.1


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

* [PATCH 081/118] drbd: Converted drbd_send_handshake() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (79 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 080/118] drbd: Converted drbd_recv_fp() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 082/118] drbd: Converted drbd_recv() " Philipp Reisner
                   ` (38 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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_receiver.c |   20 ++++++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 615405d..d238bb1 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -377,7 +377,7 @@ struct p_block_req {
  */
 
 struct p_handshake {
-	struct p_header head;	/* Note: You must always use a h80 here */
+	struct p_header head;   /* Note: vnr will be ignored */
 	u32 protocol_min;
 	u32 feature_flags;
 	u32 protocol_max;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 080c91b..e4aa2d6 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3956,28 +3956,28 @@ static void drbd_disconnect(struct drbd_conf *mdev)
  *
  * for now, they are expected to be zero, but ignored.
  */
-static int drbd_send_handshake(struct drbd_conf *mdev)
+static int drbd_send_handshake(struct drbd_tconn *tconn)
 {
 	/* ASSERT current == mdev->tconn->receiver ... */
-	struct p_handshake *p = &mdev->tconn->data.sbuf.handshake;
+	struct p_handshake *p = &tconn->data.sbuf.handshake;
 	int ok;
 
-	if (mutex_lock_interruptible(&mdev->tconn->data.mutex)) {
-		dev_err(DEV, "interrupted during initial handshake\n");
+	if (mutex_lock_interruptible(&tconn->data.mutex)) {
+		conn_err(tconn, "interrupted during initial handshake\n");
 		return 0; /* interrupted. not ok. */
 	}
 
-	if (mdev->tconn->data.socket == NULL) {
-		mutex_unlock(&mdev->tconn->data.mutex);
+	if (tconn->data.socket == NULL) {
+		mutex_unlock(&tconn->data.mutex);
 		return 0;
 	}
 
 	memset(p, 0, sizeof(*p));
 	p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
 	p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
-	ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_HAND_SHAKE,
-			    &p->head, sizeof(*p), 0 );
-	mutex_unlock(&mdev->tconn->data.mutex);
+	ok = _conn_send_cmd(tconn, 0, tconn->data.socket, P_HAND_SHAKE,
+			    &p->head, sizeof(*p), 0);
+	mutex_unlock(&tconn->data.mutex);
 	return ok;
 }
 
@@ -3997,7 +3997,7 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	enum drbd_packet cmd;
 	int rv;
 
-	rv = drbd_send_handshake(mdev);
+	rv = drbd_send_handshake(mdev->tconn);
 	if (!rv)
 		return 0;
 
-- 
1.7.4.1


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

* [PATCH 082/118] drbd: Converted drbd_recv() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (80 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 081/118] drbd: Converted drbd_send_handshake() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 083/118] drbd: struct packet_info to hold information of decoded packets Philipp Reisner
                   ` (37 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e4aa2d6..6283911 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -498,7 +498,7 @@ static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flag
 	return rv;
 }
 
-static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
+static int drbd_recv(struct drbd_tconn *tconn, void *buf, size_t size)
 {
 	mm_segment_t oldfs;
 	struct kvec iov = {
@@ -516,7 +516,7 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
 	set_fs(KERNEL_DS);
 
 	for (;;) {
-		rv = sock_recvmsg(mdev->tconn->data.socket, &msg, size, msg.msg_flags);
+		rv = sock_recvmsg(tconn->data.socket, &msg, size, msg.msg_flags);
 		if (rv == size)
 			break;
 
@@ -527,12 +527,12 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
 
 		if (rv < 0) {
 			if (rv == -ECONNRESET)
-				dev_info(DEV, "sock was reset by peer\n");
+				conn_info(tconn, "sock was reset by peer\n");
 			else if (rv != -ERESTARTSYS)
-				dev_err(DEV, "sock_recvmsg returned %d\n", rv);
+				conn_err(tconn, "sock_recvmsg returned %d\n", rv);
 			break;
 		} else if (rv == 0) {
-			dev_info(DEV, "sock was shut down by peer\n");
+			conn_info(tconn, "sock was shut down by peer\n");
 			break;
 		} else	{
 			/* signal came in, or peer/link went down,
@@ -546,7 +546,7 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
 	set_fs(oldfs);
 
 	if (rv != size)
-		drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE));
+		drbd_force_state(tconn->volume0, NS(conn, C_BROKEN_PIPE));
 
 	return rv;
 }
@@ -953,7 +953,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
 	struct p_header *h = &mdev->tconn->data.rbuf.header;
 	int r;
 
-	r = drbd_recv(mdev, h, sizeof(*h));
+	r = drbd_recv(mdev->tconn, h, sizeof(*h));
 	if (unlikely(r != sizeof(*h))) {
 		if (!signal_pending(current))
 			dev_warn(DEV, "short read expecting header on sock: r=%d\n", r);
@@ -1276,7 +1276,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 
 	if (dgs) {
-		rr = drbd_recv(mdev, dig_in, dgs);
+		rr = drbd_recv(mdev->tconn, dig_in, dgs);
 		if (rr != dgs) {
 			if (!signal_pending(current))
 				dev_warn(DEV,
@@ -1317,7 +1317,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
 	page_chain_for_each(page) {
 		unsigned len = min_t(int, ds, PAGE_SIZE);
 		data = kmap(page);
-		rr = drbd_recv(mdev, data, len);
+		rr = drbd_recv(mdev->tconn, data, len);
 		if (drbd_insert_fault(mdev, DRBD_FAULT_RECEIVE)) {
 			dev_err(DEV, "Fault injection: Corrupting data on receive\n");
 			data[0] = data[0] ^ (unsigned long)-1;
@@ -1364,7 +1364,7 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
 
 	data = kmap(page);
 	while (data_size) {
-		rr = drbd_recv(mdev, data, min_t(int, data_size, PAGE_SIZE));
+		rr = drbd_recv(mdev->tconn, data, min_t(int, data_size, PAGE_SIZE));
 		if (rr != min_t(int, data_size, PAGE_SIZE)) {
 			rv = 0;
 			if (!signal_pending(current))
@@ -1393,7 +1393,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 		crypto_hash_digestsize(mdev->tconn->integrity_r_tfm) : 0;
 
 	if (dgs) {
-		rr = drbd_recv(mdev, dig_in, dgs);
+		rr = drbd_recv(mdev->tconn, dig_in, dgs);
 		if (rr != dgs) {
 			if (!signal_pending(current))
 				dev_warn(DEV,
@@ -1414,7 +1414,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 
 	bio_for_each_segment(bvec, bio, i) {
 		expect = min_t(int, data_size, bvec->bv_len);
-		rr = drbd_recv(mdev,
+		rr = drbd_recv(mdev->tconn,
 			     kmap(bvec->bv_page)+bvec->bv_offset,
 			     expect);
 		kunmap(bvec->bv_page);
@@ -2098,7 +2098,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 		peer_req->digest = di;
 		peer_req->flags |= EE_HAS_DIGEST;
 
-		if (drbd_recv(mdev, di->digest, digest_size) != digest_size)
+		if (drbd_recv(mdev->tconn, di->digest, digest_size) != digest_size)
 			goto out_free_e;
 
 		if (cmd == P_CSUM_RS_REQUEST) {
@@ -2789,7 +2789,7 @@ static int receive_protocol(struct drbd_conf *mdev, enum drbd_packet cmd,
 	if (mdev->tconn->agreed_pro_version >= 87) {
 		unsigned char *my_alg = mdev->tconn->net_conf->integrity_alg;
 
-		if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size)
+		if (drbd_recv(mdev->tconn, p_integrity_alg, data_size) != data_size)
 			return false;
 
 		p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
@@ -2875,7 +2875,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
 	/* initialize verify_alg and csums_alg */
 	memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
 
-	if (drbd_recv(mdev, &p->head.payload, header_size) != header_size)
+	if (drbd_recv(mdev->tconn, &p->head.payload, header_size) != header_size)
 		return false;
 
 	mdev->sync_conf.rate	  = be32_to_cpu(p->rate);
@@ -2889,7 +2889,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
 				return false;
 			}
 
-			if (drbd_recv(mdev, p->verify_alg, data_size) != data_size)
+			if (drbd_recv(mdev->tconn, p->verify_alg, data_size) != data_size)
 				return false;
 
 			/* we expect NUL terminated string */
@@ -3428,7 +3428,7 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
 	}
 	if (want == 0)
 		return 0;
-	err = drbd_recv(mdev, buffer, want);
+	err = drbd_recv(mdev->tconn, buffer, want);
 	if (err != want) {
 		if (err >= 0)
 			err = -EIO;
@@ -3617,7 +3617,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
 			/* use the page buff */
 			p = buffer;
 			memcpy(p, h, sizeof(*h));
-			if (drbd_recv(mdev, p->head.payload, data_size) != data_size)
+			if (drbd_recv(mdev->tconn, p->head.payload, data_size) != data_size)
 				goto out;
 			if (data_size <= (sizeof(*p) - sizeof(p->head))) {
 				dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size);
@@ -3681,7 +3681,7 @@ static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd,
 	size = data_size;
 	while (size > 0) {
 		want = min_t(int, size, sizeof(sink));
-		r = drbd_recv(mdev, sink, want);
+		r = drbd_recv(mdev->tconn, sink, want);
 		if (!expect(r > 0))
 			break;
 		size -= r;
@@ -3788,7 +3788,7 @@ static void drbdd(struct drbd_conf *mdev)
 		}
 
 		if (shs) {
-			rv = drbd_recv(mdev, &header->payload, shs);
+			rv = drbd_recv(mdev->tconn, &header->payload, shs);
 			if (unlikely(rv != shs)) {
 				if (!signal_pending(current))
 					dev_warn(DEV, "short read while reading sub header: rv=%d\n", rv);
@@ -4017,7 +4017,7 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 		return -1;
 	}
 
-	rv = drbd_recv(mdev, &p->head.payload, expect);
+	rv = drbd_recv(mdev->tconn, &p->head.payload, expect);
 
 	if (rv != expect) {
 		if (!signal_pending(current))
@@ -4120,7 +4120,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 		goto fail;
 	}
 
-	rv = drbd_recv(mdev, peers_ch, length);
+	rv = drbd_recv(mdev->tconn, peers_ch, length);
 
 	if (rv != length) {
 		if (!signal_pending(current))
@@ -4168,7 +4168,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 		goto fail;
 	}
 
-	rv = drbd_recv(mdev, response , resp_size);
+	rv = drbd_recv(mdev->tconn, response , resp_size);
 
 	if (rv != resp_size) {
 		if (!signal_pending(current))
-- 
1.7.4.1


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

* [PATCH 083/118] drbd: struct packet_info to hold information of decoded packets
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (81 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 082/118] drbd: Converted drbd_recv() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 084/118] drbd: Converted decode_header() from mdev to tconn Philipp Reisner
                   ` (36 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6283911..deb0837 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -48,6 +48,12 @@
 
 #include "drbd_vli.h"
 
+struct packet_info {
+	enum drbd_packet cmd;
+	int size;
+	int vnr;
+};
+
 enum finish_epoch {
 	FE_STILL_LIVE,
 	FE_DESTROYED,
@@ -924,19 +930,18 @@ out_release_sockets:
 	return -1;
 }
 
-static bool decode_header(struct drbd_conf *mdev, struct p_header *h,
-			  enum drbd_packet *cmd, unsigned int *packet_size)
+static bool decode_header(struct drbd_conf *mdev, struct p_header *h, struct packet_info *pi)
 {
 	u32 vol_n_len;
 
 	if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
-		*cmd = be16_to_cpu(h->h80.command);
-		*packet_size = be16_to_cpu(h->h80.length);
+		pi->cmd = be16_to_cpu(h->h80.command);
+		pi->size = be16_to_cpu(h->h80.length);
 	} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
-		*cmd = be16_to_cpu(h->h95.command);
+		pi->cmd = be16_to_cpu(h->h95.command);
 		vol_n_len = be32_to_cpu(h->h95.vol_n_len);
-		*packet_size = vol_n_len & 0x00ffffff;
-		/* vnr = vol_n_len >> 24; */
+		pi->size = vol_n_len & 0x00ffffff;
+		pi->vnr  = vol_n_len >> 24;
 	} else {
 		dev_err(DEV, "magic?? on data m: 0x%08x c: %d l: %d\n",
 		    be32_to_cpu(h->h80.magic),
@@ -947,8 +952,7 @@ static bool decode_header(struct drbd_conf *mdev, struct p_header *h,
 	return true;
 }
 
-static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
-			    unsigned int *packet_size)
+static int drbd_recv_header(struct drbd_conf *mdev, struct packet_info *pi)
 {
 	struct p_header *h = &mdev->tconn->data.rbuf.header;
 	int r;
@@ -960,7 +964,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
 		return false;
 	}
 
-	r = decode_header(mdev, h, cmd, packet_size);
+	r = decode_header(mdev, h, pi);
 	mdev->tconn->last_received = jiffies;
 
 	return r;
@@ -3584,6 +3588,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
 	int err;
 	int ok = false;
 	struct p_header *h = &mdev->tconn->data.rbuf.header;
+	struct packet_info pi;
 
 	drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
 	/* you are supposed to send additional out-of-sync information
@@ -3637,8 +3642,10 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
 				goto out;
 			break;
 		}
-		if (!drbd_recv_header(mdev, &cmd, &data_size))
+		if (!drbd_recv_header(mdev, &pi))
 			goto out;
+		cmd = pi.cmd;
+		data_size = pi.size;
 	}
 
 	INFO_bm_xfer_stats(mdev, "receive", &c);
@@ -3766,24 +3773,23 @@ static struct data_cmd drbd_cmd_handler[] = {
 static void drbdd(struct drbd_conf *mdev)
 {
 	struct p_header *header = &mdev->tconn->data.rbuf.header;
-	unsigned int packet_size;
-	enum drbd_packet cmd;
+	struct packet_info pi;
 	size_t shs; /* sub header size */
 	int rv;
 
 	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
-		if (!drbd_recv_header(mdev, &cmd, &packet_size))
+		if (!drbd_recv_header(mdev, &pi))
 			goto err_out;
 
-		if (unlikely(cmd >= P_MAX_CMD || !drbd_cmd_handler[cmd].function)) {
-			dev_err(DEV, "unknown packet type %d, l: %d!\n", cmd, packet_size);
+		if (unlikely(pi.cmd >= P_MAX_CMD || !drbd_cmd_handler[pi.cmd].function)) {
+			dev_err(DEV, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
 			goto err_out;
 		}
 
-		shs = drbd_cmd_handler[cmd].pkt_size - sizeof(struct p_header);
-		if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
-			dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
+		shs = drbd_cmd_handler[pi.cmd].pkt_size - sizeof(struct p_header);
+		if (pi.size - shs > 0 && !drbd_cmd_handler[pi.cmd].expect_payload) {
+			dev_err(DEV, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
 			goto err_out;
 		}
 
@@ -3796,11 +3802,11 @@ static void drbdd(struct drbd_conf *mdev)
 			}
 		}
 
-		rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs);
+		rv = drbd_cmd_handler[pi.cmd].function(mdev, pi.cmd, pi.size - shs);
 
 		if (unlikely(!rv)) {
 			dev_err(DEV, "error receiving %s, l: %d!\n",
-			    cmdname(cmd), packet_size);
+			    cmdname(pi.cmd), pi.size);
 			goto err_out;
 		}
 	}
@@ -3993,27 +3999,26 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	/* ASSERT current == mdev->tconn->receiver ... */
 	struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
 	const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
-	unsigned int length;
-	enum drbd_packet cmd;
+	struct packet_info pi;
 	int rv;
 
 	rv = drbd_send_handshake(mdev->tconn);
 	if (!rv)
 		return 0;
 
-	rv = drbd_recv_header(mdev, &cmd, &length);
+	rv = drbd_recv_header(mdev, &pi);
 	if (!rv)
 		return 0;
 
-	if (cmd != P_HAND_SHAKE) {
+	if (pi.cmd != P_HAND_SHAKE) {
 		dev_err(DEV, "expected HandShake packet, received: %s (0x%04x)\n",
-		     cmdname(cmd), cmd);
+		     cmdname(pi.cmd), pi.cmd);
 		return -1;
 	}
 
-	if (length != expect) {
+	if (pi.size != expect) {
 		dev_err(DEV, "expected HandShake length: %u, received: %u\n",
-		     expect, length);
+		     expect, pi.size);
 		return -1;
 	}
 
@@ -4075,8 +4080,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
 	unsigned int resp_size;
 	struct hash_desc desc;
-	enum drbd_packet cmd;
-	unsigned int length;
+	struct packet_info pi;
 	int rv;
 
 	desc.tfm = mdev->tconn->cram_hmac_tfm;
@@ -4096,33 +4100,33 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev, &cmd, &length);
+	rv = drbd_recv_header(mdev, &pi);
 	if (!rv)
 		goto fail;
 
-	if (cmd != P_AUTH_CHALLENGE) {
+	if (pi.cmd != P_AUTH_CHALLENGE) {
 		dev_err(DEV, "expected AuthChallenge packet, received: %s (0x%04x)\n",
-		    cmdname(cmd), cmd);
+		    cmdname(pi.cmd), pi.cmd);
 		rv = 0;
 		goto fail;
 	}
 
-	if (length > CHALLENGE_LEN * 2) {
+	if (pi.size > CHALLENGE_LEN * 2) {
 		dev_err(DEV, "expected AuthChallenge payload too big.\n");
 		rv = -1;
 		goto fail;
 	}
 
-	peers_ch = kmalloc(length, GFP_NOIO);
+	peers_ch = kmalloc(pi.size, GFP_NOIO);
 	if (peers_ch == NULL) {
 		dev_err(DEV, "kmalloc of peers_ch failed\n");
 		rv = -1;
 		goto fail;
 	}
 
-	rv = drbd_recv(mdev->tconn, peers_ch, length);
+	rv = drbd_recv(mdev->tconn, peers_ch, pi.size);
 
-	if (rv != length) {
+	if (rv != pi.size) {
 		if (!signal_pending(current))
 			dev_warn(DEV, "short read AuthChallenge: l=%u\n", rv);
 		rv = 0;
@@ -4138,7 +4142,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	}
 
 	sg_init_table(&sg, 1);
-	sg_set_buf(&sg, peers_ch, length);
+	sg_set_buf(&sg, peers_ch, pi.size);
 
 	rv = crypto_hash_digest(&desc, &sg, sg.length, response);
 	if (rv) {
@@ -4151,18 +4155,18 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev, &cmd, &length);
+	rv = drbd_recv_header(mdev, &pi);
 	if (!rv)
 		goto fail;
 
-	if (cmd != P_AUTH_RESPONSE) {
+	if (pi.cmd != P_AUTH_RESPONSE) {
 		dev_err(DEV, "expected AuthResponse packet, received: %s (0x%04x)\n",
-			cmdname(cmd), cmd);
+			cmdname(pi.cmd), pi.cmd);
 		rv = 0;
 		goto fail;
 	}
 
-	if (length != resp_size) {
+	if (pi.size != resp_size) {
 		dev_err(DEV, "expected AuthResponse payload of wrong size\n");
 		rv = 0;
 		goto fail;
@@ -4548,14 +4552,14 @@ int drbd_asender(struct drbd_thread *thi)
 	struct drbd_conf *mdev = thi->mdev;
 	struct p_header *h = &mdev->tconn->meta.rbuf.header;
 	struct asender_cmd *cmd = NULL;
+	struct packet_info pi;
 
 	int rv;
 	void *buf    = h;
 	int received = 0;
 	int expect   = sizeof(struct p_header);
 	int ping_timeout_active = 0;
-	int empty, pkt_size;
-	enum drbd_packet cmd_nr;
+	int empty;
 
 	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
 
@@ -4644,25 +4648,25 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (!decode_header(mdev, h, &cmd_nr, &pkt_size))
+			if (!decode_header(mdev, h, &pi))
 				goto reconnect;
-			cmd = get_asender_cmd(cmd_nr);
+			cmd = get_asender_cmd(pi.cmd);
 			if (unlikely(cmd == NULL)) {
 				dev_err(DEV, "unknown command %d on meta (l: %d)\n",
-					cmd_nr, pkt_size);
+					pi.cmd, pi.size);
 				goto disconnect;
 			}
 			expect = cmd->pkt_size;
-			if (pkt_size != expect - sizeof(struct p_header)) {
+			if (pi.size != expect - sizeof(struct p_header)) {
 				dev_err(DEV, "Wrong packet size on meta (c: %d, l: %d)\n",
-					cmd_nr, pkt_size);
+					pi.cmd, pi.size);
 				goto reconnect;
 			}
 		}
 		if (received == expect) {
 			mdev->tconn->last_received = jiffies;
 			D_ASSERT(cmd != NULL);
-			if (!cmd->process(mdev, cmd_nr))
+			if (!cmd->process(mdev, pi.cmd))
 				goto reconnect;
 
 			/* the idle_timeout (ping-int)
-- 
1.7.4.1


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

* [PATCH 084/118] drbd: Converted decode_header() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (82 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 083/118] drbd: struct packet_info to hold information of decoded packets Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 085/118] drbd: Converted drbd_recv_header() " Philipp Reisner
                   ` (35 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index deb0837..66b35e9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -930,7 +930,7 @@ out_release_sockets:
 	return -1;
 }
 
-static bool decode_header(struct drbd_conf *mdev, struct p_header *h, struct packet_info *pi)
+static bool decode_header(struct drbd_tconn *tconn, struct p_header *h, struct packet_info *pi)
 {
 	u32 vol_n_len;
 
@@ -943,7 +943,7 @@ static bool decode_header(struct drbd_conf *mdev, struct p_header *h, struct pac
 		pi->size = vol_n_len & 0x00ffffff;
 		pi->vnr  = vol_n_len >> 24;
 	} else {
-		dev_err(DEV, "magic?? on data m: 0x%08x c: %d l: %d\n",
+		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));
@@ -964,7 +964,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, struct packet_info *pi)
 		return false;
 	}
 
-	r = decode_header(mdev, h, pi);
+	r = decode_header(mdev->tconn, h, pi);
 	mdev->tconn->last_received = jiffies;
 
 	return r;
@@ -4648,7 +4648,7 @@ int drbd_asender(struct drbd_thread *thi)
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (!decode_header(mdev, h, &pi))
+			if (!decode_header(mdev->tconn, h, &pi))
 				goto reconnect;
 			cmd = get_asender_cmd(pi.cmd);
 			if (unlikely(cmd == NULL)) {
-- 
1.7.4.1


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

* [PATCH 085/118] drbd: Converted drbd_recv_header() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (83 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 084/118] drbd: Converted decode_header() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 086/118] drbd: Converted drbd_do_handshake() " Philipp Reisner
                   ` (34 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 66b35e9..4369651 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -952,20 +952,20 @@ static bool decode_header(struct drbd_tconn *tconn, struct p_header *h, struct p
 	return true;
 }
 
-static int drbd_recv_header(struct drbd_conf *mdev, struct packet_info *pi)
+static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi)
 {
-	struct p_header *h = &mdev->tconn->data.rbuf.header;
+	struct p_header *h = &tconn->data.rbuf.header;
 	int r;
 
-	r = drbd_recv(mdev->tconn, h, sizeof(*h));
+	r = drbd_recv(tconn, h, sizeof(*h));
 	if (unlikely(r != sizeof(*h))) {
 		if (!signal_pending(current))
-			dev_warn(DEV, "short read expecting header on sock: r=%d\n", r);
+			conn_warn(tconn, "short read expecting header on sock: r=%d\n", r);
 		return false;
 	}
 
-	r = decode_header(mdev->tconn, h, pi);
-	mdev->tconn->last_received = jiffies;
+	r = decode_header(tconn, h, pi);
+	tconn->last_received = jiffies;
 
 	return r;
 }
@@ -3642,7 +3642,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
 				goto out;
 			break;
 		}
-		if (!drbd_recv_header(mdev, &pi))
+		if (!drbd_recv_header(mdev->tconn, &pi))
 			goto out;
 		cmd = pi.cmd;
 		data_size = pi.size;
@@ -3779,7 +3779,7 @@ static void drbdd(struct drbd_conf *mdev)
 
 	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
 		drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
-		if (!drbd_recv_header(mdev, &pi))
+		if (!drbd_recv_header(mdev->tconn, &pi))
 			goto err_out;
 
 		if (unlikely(pi.cmd >= P_MAX_CMD || !drbd_cmd_handler[pi.cmd].function)) {
@@ -4006,7 +4006,7 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	if (!rv)
 		return 0;
 
-	rv = drbd_recv_header(mdev, &pi);
+	rv = drbd_recv_header(mdev->tconn, &pi);
 	if (!rv)
 		return 0;
 
@@ -4100,7 +4100,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev, &pi);
+	rv = drbd_recv_header(mdev->tconn, &pi);
 	if (!rv)
 		goto fail;
 
@@ -4155,7 +4155,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev, &pi);
+	rv = drbd_recv_header(mdev->tconn, &pi);
 	if (!rv)
 		goto fail;
 
-- 
1.7.4.1


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

* [PATCH 086/118] drbd: Converted drbd_do_handshake() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (84 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 085/118] drbd: Converted drbd_recv_header() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 087/118] drbd: Converted drbd_(get|put)_data_sock() and drbd_send_cmd2() " Philipp Reisner
                   ` (33 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 4369651..7c6c385 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -60,7 +60,7 @@ enum finish_epoch {
 	FE_RECYCLED,
 };
 
-static int drbd_do_handshake(struct drbd_conf *mdev);
+static int drbd_do_handshake(struct drbd_tconn *tconn);
 static int drbd_do_auth(struct drbd_conf *mdev);
 
 static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
@@ -883,7 +883,7 @@ retry:
 
 	D_ASSERT(mdev->tconn->asender.task == NULL);
 
-	h = drbd_do_handshake(mdev);
+	h = drbd_do_handshake(mdev->tconn);
 	if (h <= 0)
 		return h;
 
@@ -3994,39 +3994,39 @@ static int drbd_send_handshake(struct drbd_tconn *tconn)
  *  -1 peer talks different language,
  *     no point in trying again, please go standalone.
  */
-static int drbd_do_handshake(struct drbd_conf *mdev)
+static int drbd_do_handshake(struct drbd_tconn *tconn)
 {
-	/* ASSERT current == mdev->tconn->receiver ... */
-	struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
+	/* ASSERT current == tconn->receiver ... */
+	struct p_handshake *p = &tconn->data.rbuf.handshake;
 	const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
 	struct packet_info pi;
 	int rv;
 
-	rv = drbd_send_handshake(mdev->tconn);
+	rv = drbd_send_handshake(tconn);
 	if (!rv)
 		return 0;
 
-	rv = drbd_recv_header(mdev->tconn, &pi);
+	rv = drbd_recv_header(tconn, &pi);
 	if (!rv)
 		return 0;
 
 	if (pi.cmd != P_HAND_SHAKE) {
-		dev_err(DEV, "expected HandShake packet, received: %s (0x%04x)\n",
+		conn_err(tconn, "expected HandShake packet, received: %s (0x%04x)\n",
 		     cmdname(pi.cmd), pi.cmd);
 		return -1;
 	}
 
 	if (pi.size != expect) {
-		dev_err(DEV, "expected HandShake length: %u, received: %u\n",
+		conn_err(tconn, "expected HandShake length: %u, received: %u\n",
 		     expect, pi.size);
 		return -1;
 	}
 
-	rv = drbd_recv(mdev->tconn, &p->head.payload, expect);
+	rv = drbd_recv(tconn, &p->head.payload, expect);
 
 	if (rv != expect) {
 		if (!signal_pending(current))
-			dev_warn(DEV, "short read receiving handshake packet: l=%u\n", rv);
+			conn_warn(tconn, "short read receiving handshake packet: l=%u\n", rv);
 		return 0;
 	}
 
@@ -4039,15 +4039,15 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
 	    PRO_VERSION_MIN > p->protocol_max)
 		goto incompat;
 
-	mdev->tconn->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
+	tconn->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
 
-	dev_info(DEV, "Handshake successful: "
-	     "Agreed network protocol version %d\n", mdev->tconn->agreed_pro_version);
+	conn_info(tconn, "Handshake successful: "
+	     "Agreed network protocol version %d\n", tconn->agreed_pro_version);
 
 	return 1;
 
  incompat:
-	dev_err(DEV, "incompatible DRBD dialects: "
+	conn_err(tconn, "incompatible DRBD dialects: "
 	    "I support %d-%d, peer supports %d-%d\n",
 	    PRO_VERSION_MIN, PRO_VERSION_MAX,
 	    p->protocol_min, p->protocol_max);
-- 
1.7.4.1


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

* [PATCH 087/118] drbd: Converted drbd_(get|put)_data_sock() and drbd_send_cmd2() to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (85 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 086/118] drbd: Converted drbd_do_handshake() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 088/118] drbd: Converted drbd_do_auth() from mdev " Philipp Reisner
                   ` (32 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d238bb1..ddff35b 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1108,26 +1108,26 @@ static inline unsigned int mdev_to_minor(struct drbd_conf *mdev)
 /* returns 1 if it was successful,
  * returns 0 if there was no data socket.
  * so wherever you are going to use the data.socket, e.g. do
- * if (!drbd_get_data_sock(mdev))
+ * if (!drbd_get_data_sock(mdev->tconn))
  *	return 0;
  *	CODE();
- * drbd_put_data_sock(mdev);
+ * drbd_get_data_sock(mdev->tconn);
  */
-static inline int drbd_get_data_sock(struct drbd_conf *mdev)
+static inline int drbd_get_data_sock(struct drbd_tconn *tconn)
 {
-	mutex_lock(&mdev->tconn->data.mutex);
+	mutex_lock(&tconn->data.mutex);
 	/* drbd_disconnect() could have called drbd_free_sock()
 	 * while we were waiting in down()... */
-	if (unlikely(mdev->tconn->data.socket == NULL)) {
-		mutex_unlock(&mdev->tconn->data.mutex);
+	if (unlikely(tconn->data.socket == NULL)) {
+		mutex_unlock(&tconn->data.mutex);
 		return 0;
 	}
 	return 1;
 }
 
-static inline void drbd_put_data_sock(struct drbd_conf *mdev)
+static inline void drbd_put_data_sock(struct drbd_tconn *tconn)
 {
-	mutex_unlock(&mdev->tconn->data.mutex);
+	mutex_unlock(&tconn->data.mutex);
 }
 
 /*
@@ -1170,12 +1170,12 @@ extern int drbd_send_state(struct drbd_conf *mdev);
 extern int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct socket *sock,
 			  enum drbd_packet cmd, struct p_header *h, size_t size,
 			  unsigned msg_flags);
+extern int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd,
+			  char *data, size_t size);
 #define USE_DATA_SOCKET 1
 #define USE_META_SOCKET 0
 extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 			 enum drbd_packet cmd, struct p_header *h, size_t size);
-extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd,
-			  char *data, size_t size);
 extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc);
 extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
 			u32 set_size);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 544171a..14961d8 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -739,23 +739,23 @@ int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
 	return ok;
 }
 
-int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packet cmd, char *data,
+int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
 		   size_t size)
 {
-	struct p_header h;
+	struct p_header80 h;
 	int ok;
 
-	prepare_header(mdev, &h, cmd, size);
+	prepare_header80(&h, cmd, size);
 
-	if (!drbd_get_data_sock(mdev))
+	if (!drbd_get_data_sock(tconn))
 		return 0;
 
 	ok = (sizeof(h) ==
-		drbd_send(mdev->tconn, mdev->tconn->data.socket, &h, sizeof(h), 0));
+		drbd_send(tconn, tconn->data.socket, &h, sizeof(h), 0));
 	ok = ok && (size ==
-		drbd_send(mdev->tconn, mdev->tconn->data.socket, data, size, 0));
+		drbd_send(tconn, tconn->data.socket, data, size, 0));
 
-	drbd_put_data_sock(mdev);
+	drbd_put_data_sock(tconn);
 
 	return ok;
 }
@@ -1200,10 +1200,10 @@ int drbd_send_bitmap(struct drbd_conf *mdev)
 {
 	int err;
 
-	if (!drbd_get_data_sock(mdev))
+	if (!drbd_get_data_sock(mdev->tconn))
 		return -1;
 	err = !_drbd_send_bitmap(mdev);
-	drbd_put_data_sock(mdev);
+	drbd_put_data_sock(mdev->tconn);
 	return err;
 }
 
@@ -1517,7 +1517,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 	void *dgb;
 	int dgs;
 
-	if (!drbd_get_data_sock(mdev))
+	if (!drbd_get_data_sock(mdev->tconn))
 		return 0;
 
 	dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_w_tfm) ?
@@ -1576,7 +1576,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
 		} */
 	}
 
-	drbd_put_data_sock(mdev);
+	drbd_put_data_sock(mdev->tconn);
 
 	return ok;
 }
@@ -1607,7 +1607,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	 * This one may be interrupted by DRBD_SIG and/or DRBD_SIGKILL
 	 * in response to admin command or module unload.
 	 */
-	if (!drbd_get_data_sock(mdev))
+	if (!drbd_get_data_sock(mdev->tconn))
 		return 0;
 
 	ok = sizeof(p) == drbd_send(mdev->tconn, mdev->tconn->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0);
@@ -1619,7 +1619,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
 	if (ok)
 		ok = _drbd_send_zc_ee(mdev, peer_req);
 
-	drbd_put_data_sock(mdev);
+	drbd_put_data_sock(mdev->tconn);
 
 	return ok;
 }
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 7c6c385..4b637bf 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4096,7 +4096,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 
 	get_random_bytes(my_challenge, CHALLENGE_LEN);
 
-	rv = drbd_send_cmd2(mdev, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
+	rv = conn_send_cmd2(mdev->tconn, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
 	if (!rv)
 		goto fail;
 
@@ -4151,7 +4151,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 		goto fail;
 	}
 
-	rv = drbd_send_cmd2(mdev, P_AUTH_RESPONSE, response, resp_size);
+	rv = conn_send_cmd2(mdev->tconn, P_AUTH_RESPONSE, response, resp_size);
 	if (!rv)
 		goto fail;
 
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 5be179b..f5c27bb 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1197,7 +1197,7 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	if (cancel)
 		return 1;
 
-	if (!drbd_get_data_sock(mdev))
+	if (!drbd_get_data_sock(mdev->tconn))
 		return 0;
 	p->barrier = b->br_number;
 	/* inc_ap_pending was done where this was queued.
@@ -1205,7 +1205,7 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	 * or (on connection loss) in w_clear_epoch.  */
 	ok = _drbd_send_cmd(mdev, mdev->tconn->data.socket, P_BARRIER,
 			    &p->head, sizeof(*p), 0);
-	drbd_put_data_sock(mdev);
+	drbd_put_data_sock(mdev->tconn);
 
 	return ok;
 }
-- 
1.7.4.1


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

* [PATCH 088/118] drbd: Converted drbd_do_auth() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (86 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 087/118] drbd: Converted drbd_(get|put)_data_sock() and drbd_send_cmd2() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 089/118] drbd: Converted drbd_send_protocol() " Philipp Reisner
                   ` (31 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 4b637bf..95b0d6c 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -61,7 +61,7 @@ enum finish_epoch {
 };
 
 static int drbd_do_handshake(struct drbd_tconn *tconn);
-static int drbd_do_auth(struct drbd_conf *mdev);
+static int drbd_do_auth(struct drbd_tconn *tconn);
 
 static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
 static int e_end_block(struct drbd_conf *, struct drbd_work *, int);
@@ -889,7 +889,7 @@ retry:
 
 	if (mdev->tconn->cram_hmac_tfm) {
 		/* drbd_request_state(mdev, NS(conn, WFAuth)); */
-		switch (drbd_do_auth(mdev)) {
+		switch (drbd_do_auth(mdev->tconn)) {
 		case -1:
 			dev_err(DEV, "Authentication of peer failed\n");
 			return -1;
@@ -4055,7 +4055,7 @@ static int drbd_do_handshake(struct drbd_tconn *tconn)
 }
 
 #if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE)
-static int drbd_do_auth(struct drbd_conf *mdev)
+static int drbd_do_auth(struct drbd_tconn *tconn)
 {
 	dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
 	dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
@@ -4070,73 +4070,73 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	-1 - auth failed, don't try again.
 */
 
-static int drbd_do_auth(struct drbd_conf *mdev)
+static int drbd_do_auth(struct drbd_tconn *tconn)
 {
 	char my_challenge[CHALLENGE_LEN];  /* 64 Bytes... */
 	struct scatterlist sg;
 	char *response = NULL;
 	char *right_response = NULL;
 	char *peers_ch = NULL;
-	unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
+	unsigned int key_len = strlen(tconn->net_conf->shared_secret);
 	unsigned int resp_size;
 	struct hash_desc desc;
 	struct packet_info pi;
 	int rv;
 
-	desc.tfm = mdev->tconn->cram_hmac_tfm;
+	desc.tfm = tconn->cram_hmac_tfm;
 	desc.flags = 0;
 
-	rv = crypto_hash_setkey(mdev->tconn->cram_hmac_tfm,
-				(u8 *)mdev->tconn->net_conf->shared_secret, key_len);
+	rv = crypto_hash_setkey(tconn->cram_hmac_tfm,
+				(u8 *)tconn->net_conf->shared_secret, key_len);
 	if (rv) {
-		dev_err(DEV, "crypto_hash_setkey() failed with %d\n", rv);
+		conn_err(tconn, "crypto_hash_setkey() failed with %d\n", rv);
 		rv = -1;
 		goto fail;
 	}
 
 	get_random_bytes(my_challenge, CHALLENGE_LEN);
 
-	rv = conn_send_cmd2(mdev->tconn, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
+	rv = conn_send_cmd2(tconn, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev->tconn, &pi);
+	rv = drbd_recv_header(tconn, &pi);
 	if (!rv)
 		goto fail;
 
 	if (pi.cmd != P_AUTH_CHALLENGE) {
-		dev_err(DEV, "expected AuthChallenge packet, received: %s (0x%04x)\n",
+		conn_err(tconn, "expected AuthChallenge packet, received: %s (0x%04x)\n",
 		    cmdname(pi.cmd), pi.cmd);
 		rv = 0;
 		goto fail;
 	}
 
 	if (pi.size > CHALLENGE_LEN * 2) {
-		dev_err(DEV, "expected AuthChallenge payload too big.\n");
+		conn_err(tconn, "expected AuthChallenge payload too big.\n");
 		rv = -1;
 		goto fail;
 	}
 
 	peers_ch = kmalloc(pi.size, GFP_NOIO);
 	if (peers_ch == NULL) {
-		dev_err(DEV, "kmalloc of peers_ch failed\n");
+		conn_err(tconn, "kmalloc of peers_ch failed\n");
 		rv = -1;
 		goto fail;
 	}
 
-	rv = drbd_recv(mdev->tconn, peers_ch, pi.size);
+	rv = drbd_recv(tconn, peers_ch, pi.size);
 
 	if (rv != pi.size) {
 		if (!signal_pending(current))
-			dev_warn(DEV, "short read AuthChallenge: l=%u\n", rv);
+			conn_warn(tconn, "short read AuthChallenge: l=%u\n", rv);
 		rv = 0;
 		goto fail;
 	}
 
-	resp_size = crypto_hash_digestsize(mdev->tconn->cram_hmac_tfm);
+	resp_size = crypto_hash_digestsize(tconn->cram_hmac_tfm);
 	response = kmalloc(resp_size, GFP_NOIO);
 	if (response == NULL) {
-		dev_err(DEV, "kmalloc of response failed\n");
+		conn_err(tconn, "kmalloc of response failed\n");
 		rv = -1;
 		goto fail;
 	}
@@ -4146,44 +4146,44 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 
 	rv = crypto_hash_digest(&desc, &sg, sg.length, response);
 	if (rv) {
-		dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
+		conn_err(tconn, "crypto_hash_digest() failed with %d\n", rv);
 		rv = -1;
 		goto fail;
 	}
 
-	rv = conn_send_cmd2(mdev->tconn, P_AUTH_RESPONSE, response, resp_size);
+	rv = conn_send_cmd2(tconn, P_AUTH_RESPONSE, response, resp_size);
 	if (!rv)
 		goto fail;
 
-	rv = drbd_recv_header(mdev->tconn, &pi);
+	rv = drbd_recv_header(tconn, &pi);
 	if (!rv)
 		goto fail;
 
 	if (pi.cmd != P_AUTH_RESPONSE) {
-		dev_err(DEV, "expected AuthResponse packet, received: %s (0x%04x)\n",
+		conn_err(tconn, "expected AuthResponse packet, received: %s (0x%04x)\n",
 			cmdname(pi.cmd), pi.cmd);
 		rv = 0;
 		goto fail;
 	}
 
 	if (pi.size != resp_size) {
-		dev_err(DEV, "expected AuthResponse payload of wrong size\n");
+		conn_err(tconn, "expected AuthResponse payload of wrong size\n");
 		rv = 0;
 		goto fail;
 	}
 
-	rv = drbd_recv(mdev->tconn, response , resp_size);
+	rv = drbd_recv(tconn, response , resp_size);
 
 	if (rv != resp_size) {
 		if (!signal_pending(current))
-			dev_warn(DEV, "short read receiving AuthResponse: l=%u\n", rv);
+			conn_warn(tconn, "short read receiving AuthResponse: l=%u\n", rv);
 		rv = 0;
 		goto fail;
 	}
 
 	right_response = kmalloc(resp_size, GFP_NOIO);
 	if (right_response == NULL) {
-		dev_err(DEV, "kmalloc of right_response failed\n");
+		conn_err(tconn, "kmalloc of right_response failed\n");
 		rv = -1;
 		goto fail;
 	}
@@ -4192,7 +4192,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 
 	rv = crypto_hash_digest(&desc, &sg, sg.length, right_response);
 	if (rv) {
-		dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
+		conn_err(tconn, "crypto_hash_digest() failed with %d\n", rv);
 		rv = -1;
 		goto fail;
 	}
@@ -4200,8 +4200,8 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 	rv = !memcmp(response, right_response, resp_size);
 
 	if (rv)
-		dev_info(DEV, "Peer authenticated using %d bytes of '%s' HMAC\n",
-		     resp_size, mdev->tconn->net_conf->cram_hmac_alg);
+		conn_info(tconn, "Peer authenticated using %d bytes of '%s' HMAC\n",
+		     resp_size, tconn->net_conf->cram_hmac_alg);
 	else
 		rv = -1;
 
-- 
1.7.4.1


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

* [PATCH 089/118] drbd: Converted drbd_send_protocol() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (87 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 088/118] drbd: Converted drbd_do_auth() from mdev " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 090/118] drbd: Use and idr data structure to map volume numbers to mdev pointers Philipp Reisner
                   ` (30 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ddff35b..9bd156a 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1160,7 +1160,7 @@ extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *);
 extern void drbd_free_sock(struct drbd_conf *mdev);
 extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
 		     void *buf, size_t size, unsigned msg_flags);
-extern int drbd_send_protocol(struct drbd_conf *mdev);
+extern int drbd_send_protocol(struct drbd_tconn *tconn);
 extern int drbd_send_uuids(struct drbd_conf *mdev);
 extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev);
 extern int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 14961d8..ca40f0a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -808,15 +808,15 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 	return rv;
 }
 
-int drbd_send_protocol(struct drbd_conf *mdev)
+int drbd_send_protocol(struct drbd_tconn *tconn)
 {
 	struct p_protocol *p;
 	int size, cf, rv;
 
 	size = sizeof(struct p_protocol);
 
-	if (mdev->tconn->agreed_pro_version >= 87)
-		size += strlen(mdev->tconn->net_conf->integrity_alg) + 1;
+	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 */
@@ -824,30 +824,30 @@ int drbd_send_protocol(struct drbd_conf *mdev)
 	if (p == NULL)
 		return 0;
 
-	p->protocol      = cpu_to_be32(mdev->tconn->net_conf->wire_protocol);
-	p->after_sb_0p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_0p);
-	p->after_sb_1p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_1p);
-	p->after_sb_2p   = cpu_to_be32(mdev->tconn->net_conf->after_sb_2p);
-	p->two_primaries = cpu_to_be32(mdev->tconn->net_conf->two_primaries);
+	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 (mdev->tconn->net_conf->want_lose)
+	if (tconn->net_conf->want_lose)
 		cf |= CF_WANT_LOSE;
-	if (mdev->tconn->net_conf->dry_run) {
-		if (mdev->tconn->agreed_pro_version >= 92)
+	if (tconn->net_conf->dry_run) {
+		if (tconn->agreed_pro_version >= 92)
 			cf |= CF_DRY_RUN;
 		else {
-			dev_err(DEV, "--dry-run is not supported by peer");
+			conn_err(tconn, "--dry-run is not supported by peer");
 			kfree(p);
 			return -1;
 		}
 	}
 	p->conn_flags    = cpu_to_be32(cf);
 
-	if (mdev->tconn->agreed_pro_version >= 87)
-		strcpy(p->integrity_alg, mdev->tconn->net_conf->integrity_alg);
+	if (tconn->agreed_pro_version >= 87)
+		strcpy(p->integrity_alg, tconn->net_conf->integrity_alg);
 
-	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL, &p->head, size);
+	rv = conn_send_cmd2(tconn, P_PROTOCOL, p->head.payload, size);
 	kfree(p);
 	return rv;
 }
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 95b0d6c..42a2b39 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -910,7 +910,7 @@ retry:
 
 	drbd_thread_start(&mdev->tconn->asender);
 
-	if (drbd_send_protocol(mdev) == -1)
+	if (drbd_send_protocol(mdev->tconn) == -1)
 		return -1;
 	drbd_send_sync_param(mdev, &mdev->sync_conf);
 	drbd_send_sizes(mdev, 0, 0);
-- 
1.7.4.1


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

* [PATCH 090/118] drbd: Use and idr data structure to map volume numbers to mdev pointers
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (88 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 089/118] drbd: Converted drbd_send_protocol() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 091/118] drbd: Converted drbd_connect() from mdev to tconn Philipp Reisner
                   ` (29 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9bd156a..4ececc3 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -40,6 +40,7 @@
 #include <linux/major.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
+#include <linux/idr.h>
 #include <net/tcp.h>
 #include <linux/lru_cache.h>
 #include <linux/prefetch.h>
@@ -915,8 +916,9 @@ struct drbd_tconn {			/* is a resource from the config file */
 	char *name;			/* Resource name */
 	struct list_head all_tconn;	/* List of all drbd_tconn, prot by global_state_lock */
 	struct drbd_conf *volume0;	/* TODO: Remove me again */
-	unsigned long flags;
+	struct idr volumes;             /* <tconn, vnr> to mdev mapping */
 
+	unsigned long flags;
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
 	atomic_t net_cnt;		/* Users of net_conf */
 	wait_queue_head_t net_cnt_wait;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ca40f0a..d7421b6 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2195,6 +2195,7 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 
 	atomic_set(&tconn->net_cnt, 0);
 	init_waitqueue_head(&tconn->net_cnt_wait);
+	idr_init(&tconn->volumes);
 
 	write_lock_irq(&global_state_lock);
 	list_add(&tconn->all_tconn, &drbd_tconns);
@@ -2214,6 +2215,7 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
 	write_lock_irq(&global_state_lock);
 	list_del(&tconn->all_tconn);
 	write_unlock_irq(&global_state_lock);
+	idr_destroy(&tconn->volumes);
 
 	kfree(tconn->name);
 	kfree(tconn->int_dig_out);
@@ -2228,6 +2230,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	struct gendisk *disk;
 	struct request_queue *q;
 	char conn_name[9]; /* drbd1234N */
+	int vnr;
 
 	/* GFP_KERNEL, we are outside of all write-out paths */
 	mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
@@ -2237,7 +2240,14 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	mdev->tconn = drbd_new_tconn(conn_name);
 	if (!mdev->tconn)
 		goto out_no_tconn;
-
+	if (!idr_pre_get(&mdev->tconn->volumes, GFP_KERNEL))
+		goto out_no_cpumask;
+	if (idr_get_new(&mdev->tconn->volumes, mdev, &vnr))
+		goto out_no_cpumask;
+	if (vnr != 0) {
+		dev_err(DEV, "vnr = %d\n", vnr);
+		goto out_no_cpumask;
+	}
 	if (!zalloc_cpumask_var(&mdev->cpu_mask, GFP_KERNEL))
 		goto out_no_cpumask;
 
-- 
1.7.4.1


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

* [PATCH 091/118] drbd: Converted drbd_connect() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (89 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 090/118] drbd: Use and idr data structure to map volume numbers to mdev pointers Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 092/118] drbd: Converted drbd_calc_cpu_mask() and drbd_thread_current_set_cpu() " Philipp Reisner
                   ` (28 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 42a2b39..b1eedd1 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -746,6 +746,24 @@ static int drbd_socket_okay(struct socket **sock)
 	}
 }
 
+static int drbd_connected(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	int ok = 1;
+
+	atomic_set(&mdev->packet_seq, 0);
+	mdev->peer_seq = 0;
+
+	ok &= drbd_send_sync_param(mdev, &mdev->sync_conf);
+	ok &= drbd_send_sizes(mdev, 0, 0);
+	ok &= drbd_send_uuids(mdev);
+	ok &= drbd_send_state(mdev);
+	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
+	clear_bit(RESIZE_PENDING, &mdev->flags);
+
+	return !ok;
+}
+
 /*
  * return values:
  *   1 yes, we have a valid connection
@@ -754,18 +772,16 @@ static int drbd_socket_okay(struct socket **sock)
  *     no point in trying again, please go standalone.
  *  -2 We do not have a network config...
  */
-static int drbd_connect(struct drbd_conf *mdev)
+static int drbd_connect(struct drbd_tconn *tconn)
 {
 	struct socket *s, *sock, *msock;
 	int try, h, ok;
 
-	D_ASSERT(!mdev->tconn->data.socket);
-
-	if (drbd_request_state(mdev, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
+	if (drbd_request_state(tconn->volume0, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
 		return -2;
 
-	clear_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
-	mdev->tconn->agreed_pro_version = 99;
+	clear_bit(DISCARD_CONCURRENT, &tconn->flags);
+	tconn->agreed_pro_version = 99;
 	/* agreed_pro_version must be smaller than 100 so we send the old
 	   header (h80) in the first packet and in the handshake packet. */
 
@@ -775,7 +791,7 @@ static int drbd_connect(struct drbd_conf *mdev)
 	do {
 		for (try = 0;;) {
 			/* 3 tries, this should take less than a second! */
-			s = drbd_try_connect(mdev->tconn);
+			s = drbd_try_connect(tconn);
 			if (s || ++try >= 3)
 				break;
 			/* give the other side time to call bind() & listen() */
@@ -784,21 +800,21 @@ static int drbd_connect(struct drbd_conf *mdev)
 
 		if (s) {
 			if (!sock) {
-				drbd_send_fp(mdev->tconn, s, P_HAND_SHAKE_S);
+				drbd_send_fp(tconn, s, P_HAND_SHAKE_S);
 				sock = s;
 				s = NULL;
 			} else if (!msock) {
-				drbd_send_fp(mdev->tconn, s, P_HAND_SHAKE_M);
+				drbd_send_fp(tconn, s, P_HAND_SHAKE_M);
 				msock = s;
 				s = NULL;
 			} else {
-				dev_err(DEV, "Logic error in drbd_connect()\n");
+				conn_err(tconn, "Logic error in drbd_connect()\n");
 				goto out_release_sockets;
 			}
 		}
 
 		if (sock && msock) {
-			schedule_timeout_interruptible(mdev->tconn->net_conf->ping_timeo*HZ/10);
+			schedule_timeout_interruptible(tconn->net_conf->ping_timeo*HZ/10);
 			ok = drbd_socket_okay(&sock);
 			ok = drbd_socket_okay(&msock) && ok;
 			if (ok)
@@ -806,41 +822,41 @@ static int drbd_connect(struct drbd_conf *mdev)
 		}
 
 retry:
-		s = drbd_wait_for_connect(mdev->tconn);
+		s = drbd_wait_for_connect(tconn);
 		if (s) {
-			try = drbd_recv_fp(mdev->tconn, s);
+			try = drbd_recv_fp(tconn, s);
 			drbd_socket_okay(&sock);
 			drbd_socket_okay(&msock);
 			switch (try) {
 			case P_HAND_SHAKE_S:
 				if (sock) {
-					dev_warn(DEV, "initial packet S crossed\n");
+					conn_warn(tconn, "initial packet S crossed\n");
 					sock_release(sock);
 				}
 				sock = s;
 				break;
 			case P_HAND_SHAKE_M:
 				if (msock) {
-					dev_warn(DEV, "initial packet M crossed\n");
+					conn_warn(tconn, "initial packet M crossed\n");
 					sock_release(msock);
 				}
 				msock = s;
-				set_bit(DISCARD_CONCURRENT, &mdev->tconn->flags);
+				set_bit(DISCARD_CONCURRENT, &tconn->flags);
 				break;
 			default:
-				dev_warn(DEV, "Error receiving initial packet\n");
+				conn_warn(tconn, "Error receiving initial packet\n");
 				sock_release(s);
 				if (random32() & 1)
 					goto retry;
 			}
 		}
 
-		if (mdev->state.conn <= C_DISCONNECTING)
+		if (tconn->volume0->state.conn <= C_DISCONNECTING)
 			goto out_release_sockets;
 		if (signal_pending(current)) {
 			flush_signals(current);
 			smp_rmb();
-			if (get_t_state(&mdev->tconn->receiver) == EXITING)
+			if (get_t_state(&tconn->receiver) == EXITING)
 				goto out_release_sockets;
 		}
 
@@ -862,65 +878,53 @@ retry:
 	msock->sk->sk_priority = TC_PRIO_INTERACTIVE;
 
 	/* NOT YET ...
-	 * sock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
+	 * sock->sk->sk_sndtimeo = tconn->net_conf->timeout*HZ/10;
 	 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 	 * first set it to the P_HAND_SHAKE timeout,
 	 * which we set to 4x the configured ping_timeout. */
 	sock->sk->sk_sndtimeo =
-	sock->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_timeo*4*HZ/10;
+	sock->sk->sk_rcvtimeo = tconn->net_conf->ping_timeo*4*HZ/10;
 
-	msock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
-	msock->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
+	msock->sk->sk_sndtimeo = tconn->net_conf->timeout*HZ/10;
+	msock->sk->sk_rcvtimeo = tconn->net_conf->ping_int*HZ;
 
 	/* we don't want delays.
 	 * we use TCP_CORK where appropriate, though */
 	drbd_tcp_nodelay(sock);
 	drbd_tcp_nodelay(msock);
 
-	mdev->tconn->data.socket = sock;
-	mdev->tconn->meta.socket = msock;
-	mdev->tconn->last_received = jiffies;
-
-	D_ASSERT(mdev->tconn->asender.task == NULL);
+	tconn->data.socket = sock;
+	tconn->meta.socket = msock;
+	tconn->last_received = jiffies;
 
-	h = drbd_do_handshake(mdev->tconn);
+	h = drbd_do_handshake(tconn);
 	if (h <= 0)
 		return h;
 
-	if (mdev->tconn->cram_hmac_tfm) {
+	if (tconn->cram_hmac_tfm) {
 		/* drbd_request_state(mdev, NS(conn, WFAuth)); */
-		switch (drbd_do_auth(mdev->tconn)) {
+		switch (drbd_do_auth(tconn)) {
 		case -1:
-			dev_err(DEV, "Authentication of peer failed\n");
+			conn_err(tconn, "Authentication of peer failed\n");
 			return -1;
 		case 0:
-			dev_err(DEV, "Authentication of peer failed, trying again.\n");
+			conn_err(tconn, "Authentication of peer failed, trying again.\n");
 			return 0;
 		}
 	}
 
-	if (drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS)
+	if (drbd_request_state(tconn->volume0, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS)
 		return 0;
 
-	sock->sk->sk_sndtimeo = mdev->tconn->net_conf->timeout*HZ/10;
+	sock->sk->sk_sndtimeo = tconn->net_conf->timeout*HZ/10;
 	sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 
-	atomic_set(&mdev->packet_seq, 0);
-	mdev->peer_seq = 0;
-
-	drbd_thread_start(&mdev->tconn->asender);
+	drbd_thread_start(&tconn->asender);
 
-	if (drbd_send_protocol(mdev->tconn) == -1)
+	if (drbd_send_protocol(tconn) == -1)
 		return -1;
-	drbd_send_sync_param(mdev, &mdev->sync_conf);
-	drbd_send_sizes(mdev, 0, 0);
-	drbd_send_uuids(mdev);
-	drbd_send_state(mdev);
-	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
-	clear_bit(RESIZE_PENDING, &mdev->flags);
-	mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */
 
-	return 1;
+	return !idr_for_each(&tconn->volumes, drbd_connected, tconn);
 
 out_release_sockets:
 	if (sock)
@@ -4225,7 +4229,7 @@ int drbdd_init(struct drbd_thread *thi)
 	dev_info(DEV, "receiver (re)started\n");
 
 	do {
-		h = drbd_connect(mdev);
+		h = drbd_connect(mdev->tconn);
 		if (h == 0) {
 			drbd_disconnect(mdev);
 			schedule_timeout_interruptible(HZ);
-- 
1.7.4.1


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

* [PATCH 092/118] drbd: Converted drbd_calc_cpu_mask() and drbd_thread_current_set_cpu() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (90 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 091/118] drbd: Converted drbd_connect() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 093/118] drbd: Converted drbdd() " Philipp Reisner
                   ` (27 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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     |   26 ++++++++++++++++----------
 drivers/block/drbd/drbd_nl.c       |    6 +++---
 drivers/block/drbd/drbd_receiver.c |    4 ++--
 drivers/block/drbd/drbd_worker.c   |    2 +-
 5 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4ececc3..ae482ed 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -945,6 +945,7 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct drbd_thread receiver;
 	struct drbd_thread worker;
 	struct drbd_thread asender;
+	cpumask_var_t cpu_mask;
 };
 
 struct drbd_conf {
@@ -1074,7 +1075,6 @@ struct drbd_conf {
 	spinlock_t peer_seq_lock;
 	unsigned int minor;
 	unsigned long comm_bm_set; /* communicated number of set bits. */
-	cpumask_var_t cpu_mask;
 	struct bm_io_work bm_io_work;
 	u64 ed_uuid; /* UUID of the exposed data */
 	struct mutex state_mutex;
@@ -1148,10 +1148,10 @@ extern int  drbd_thread_start(struct drbd_thread *thi);
 extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
 extern char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task);
 #ifdef CONFIG_SMP
-extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev, struct drbd_thread *thi);
-extern void drbd_calc_cpu_mask(struct drbd_conf *mdev);
+extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
+extern void drbd_calc_cpu_mask(struct drbd_tconn *tconn);
 #else
-#define drbd_thread_current_set_cpu(A, B) ({})
+#define drbd_thread_current_set_cpu(A) ({})
 #define drbd_calc_cpu_mask(A) ({})
 #endif
 extern void drbd_free_resources(struct drbd_conf *mdev);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index d7421b6..7612394 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -618,6 +618,12 @@ char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task)
 }
 
 #ifdef CONFIG_SMP
+static int conn_lowest_minor(struct drbd_tconn *tconn)
+{
+	int minor = 0;
+	idr_get_next(&tconn->volumes, &minor);
+	return minor;
+}
 /**
  * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
  * @mdev:	DRBD device.
@@ -625,23 +631,23 @@ char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task)
  * Forces all threads of a device onto the same CPU. This is beneficial for
  * DRBD's performance. May be overwritten by user's configuration.
  */
-void drbd_calc_cpu_mask(struct drbd_conf *mdev)
+void drbd_calc_cpu_mask(struct drbd_tconn *tconn)
 {
 	int ord, cpu;
 
 	/* user override. */
-	if (cpumask_weight(mdev->cpu_mask))
+	if (cpumask_weight(tconn->cpu_mask))
 		return;
 
-	ord = mdev_to_minor(mdev) % cpumask_weight(cpu_online_mask);
+	ord = conn_lowest_minor(tconn) % cpumask_weight(cpu_online_mask);
 	for_each_online_cpu(cpu) {
 		if (ord-- == 0) {
-			cpumask_set_cpu(cpu, mdev->cpu_mask);
+			cpumask_set_cpu(cpu, tconn->cpu_mask);
 			return;
 		}
 	}
 	/* should not be reached */
-	cpumask_setall(mdev->cpu_mask);
+	cpumask_setall(tconn->cpu_mask);
 }
 
 /**
@@ -652,14 +658,14 @@ void drbd_calc_cpu_mask(struct drbd_conf *mdev)
  * call in the "main loop" of _all_ threads, no need for any mutex, current won't die
  * prematurely.
  */
-void drbd_thread_current_set_cpu(struct drbd_conf *mdev, struct drbd_thread *thi)
+void drbd_thread_current_set_cpu(struct drbd_thread *thi)
 {
 	struct task_struct *p = current;
 
 	if (!thi->reset_cpu_mask)
 		return;
 	thi->reset_cpu_mask = 0;
-	set_cpus_allowed_ptr(p, mdev->cpu_mask);
+	set_cpus_allowed_ptr(p, thi->mdev->tconn->cpu_mask);
 }
 #endif
 
@@ -2248,7 +2254,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 		dev_err(DEV, "vnr = %d\n", vnr);
 		goto out_no_cpumask;
 	}
-	if (!zalloc_cpumask_var(&mdev->cpu_mask, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&mdev->tconn->cpu_mask, GFP_KERNEL))
 		goto out_no_cpumask;
 
 	mdev->tconn->volume0 = mdev;
@@ -2325,7 +2331,7 @@ out_no_io_page:
 out_no_disk:
 	blk_cleanup_queue(q);
 out_no_q:
-	free_cpumask_var(mdev->cpu_mask);
+	free_cpumask_var(mdev->tconn->cpu_mask);
 out_no_cpumask:
 	drbd_free_tconn(mdev->tconn);
 out_no_tconn:
@@ -2344,7 +2350,7 @@ void drbd_free_mdev(struct drbd_conf *mdev)
 	__free_page(mdev->md_io_page);
 	put_disk(mdev->vdisk);
 	blk_cleanup_queue(mdev->rq_queue);
-	free_cpumask_var(mdev->cpu_mask);
+	free_cpumask_var(mdev->tconn->cpu_mask);
 	kfree(mdev);
 }
 
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index df36a57..331495f 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1884,9 +1884,9 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
 	if (mdev->state.conn >= C_CONNECTED)
 		drbd_send_sync_param(mdev, &sc);
 
-	if (!cpumask_equal(mdev->cpu_mask, new_cpu_mask)) {
-		cpumask_copy(mdev->cpu_mask, new_cpu_mask);
-		drbd_calc_cpu_mask(mdev);
+	if (!cpumask_equal(mdev->tconn->cpu_mask, new_cpu_mask)) {
+		cpumask_copy(mdev->tconn->cpu_mask, new_cpu_mask);
+		drbd_calc_cpu_mask(mdev->tconn);
 		mdev->tconn->receiver.reset_cpu_mask = 1;
 		mdev->tconn->asender.reset_cpu_mask = 1;
 		mdev->tconn->worker.reset_cpu_mask = 1;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index b1eedd1..306532c 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3782,7 +3782,7 @@ static void drbdd(struct drbd_conf *mdev)
 	int rv;
 
 	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
+		drbd_thread_current_set_cpu(&mdev->tconn->receiver);
 		if (!drbd_recv_header(mdev->tconn, &pi))
 			goto err_out;
 
@@ -4571,7 +4571,7 @@ int drbd_asender(struct drbd_thread *thi)
 	current->rt_priority = 2;    /* more important than all other tasks */
 
 	while (get_t_state(thi) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev, thi);
+		drbd_thread_current_set_cpu(thi);
 		if (test_and_clear_bit(SEND_PING, &mdev->tconn->flags)) {
 			if (!drbd_send_ping(mdev)) {
 				dev_err(DEV, "drbd_send_ping has failed\n");
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index f5c27bb..16db1f4 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1634,7 +1634,7 @@ int drbd_worker(struct drbd_thread *thi)
 	sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev));
 
 	while (get_t_state(thi) == RUNNING) {
-		drbd_thread_current_set_cpu(mdev, thi);
+		drbd_thread_current_set_cpu(thi);
 
 		if (down_trylock(&mdev->tconn->data.work.s)) {
 			mutex_lock(&mdev->tconn->data.mutex);
-- 
1.7.4.1


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

* [PATCH 093/118] drbd: Converted drbdd() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (91 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 092/118] drbd: Converted drbd_calc_cpu_mask() and drbd_thread_current_set_cpu() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 094/118] drbd: Converted drbd_free_sock() and drbd_disconnect() " Philipp Reisner
                   ` (26 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

The drbd_md_sync(mdev) happens in the after state change anyways...

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ae482ed..70509c5 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1107,6 +1107,11 @@ static inline unsigned int mdev_to_minor(struct drbd_conf *mdev)
 	return mdev->minor;
 }
 
+static inline struct drbd_conf *vnr_to_mdev(struct drbd_tconn *tconn, int vnr)
+{
+	return (struct drbd_conf *)idr_find(&tconn->volumes, vnr);
+}
+
 /* returns 1 if it was successful,
  * returns 0 if there was no data socket.
  * so wherever you are going to use the data.socket, e.g. do
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 306532c..1d6df7a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -941,6 +941,7 @@ static bool decode_header(struct drbd_tconn *tconn, struct p_header *h, struct p
 	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);
@@ -3774,42 +3775,42 @@ static struct data_cmd drbd_cmd_handler[] = {
    p_header, but they may not rely on that. Since there is also p_header95 !
  */
 
-static void drbdd(struct drbd_conf *mdev)
+static void drbdd(struct drbd_tconn *tconn)
 {
-	struct p_header *header = &mdev->tconn->data.rbuf.header;
+	struct p_header *header = &tconn->data.rbuf.header;
 	struct packet_info pi;
 	size_t shs; /* sub header size */
 	int rv;
 
-	while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
-		drbd_thread_current_set_cpu(&mdev->tconn->receiver);
-		if (!drbd_recv_header(mdev->tconn, &pi))
+	while (get_t_state(&tconn->receiver) == RUNNING) {
+		drbd_thread_current_set_cpu(&tconn->receiver);
+		if (!drbd_recv_header(tconn, &pi))
 			goto err_out;
 
 		if (unlikely(pi.cmd >= P_MAX_CMD || !drbd_cmd_handler[pi.cmd].function)) {
-			dev_err(DEV, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
+			conn_err(tconn, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
 			goto err_out;
 		}
 
 		shs = drbd_cmd_handler[pi.cmd].pkt_size - sizeof(struct p_header);
 		if (pi.size - shs > 0 && !drbd_cmd_handler[pi.cmd].expect_payload) {
-			dev_err(DEV, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
+			conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
 			goto err_out;
 		}
 
 		if (shs) {
-			rv = drbd_recv(mdev->tconn, &header->payload, shs);
+			rv = drbd_recv(tconn, &header->payload, shs);
 			if (unlikely(rv != shs)) {
 				if (!signal_pending(current))
-					dev_warn(DEV, "short read while reading sub header: rv=%d\n", rv);
+					conn_warn(tconn, "short read while reading sub header: rv=%d\n", rv);
 				goto err_out;
 			}
 		}
 
-		rv = drbd_cmd_handler[pi.cmd].function(mdev, pi.cmd, pi.size - shs);
+		rv = drbd_cmd_handler[pi.cmd].function(vnr_to_mdev(tconn, pi.vnr), pi.cmd, pi.size - shs);
 
 		if (unlikely(!rv)) {
-			dev_err(DEV, "error receiving %s, l: %d!\n",
+			conn_err(tconn, "error receiving %s, l: %d!\n",
 			    cmdname(pi.cmd), pi.size);
 			goto err_out;
 		}
@@ -3817,11 +3818,8 @@ static void drbdd(struct drbd_conf *mdev)
 
 	if (0) {
 	err_out:
-		drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+		drbd_force_state(tconn->volume0, NS(conn, C_PROTOCOL_ERROR));
 	}
-	/* If we leave here, we probably want to update at least the
-	 * "Connected" indicator on stable storage. Do so explicitly here. */
-	drbd_md_sync(mdev);
 }
 
 void drbd_flush_workqueue(struct drbd_tconn *tconn)
@@ -4242,7 +4240,7 @@ int drbdd_init(struct drbd_thread *thi)
 
 	if (h > 0) {
 		if (get_net_conf(mdev->tconn)) {
-			drbdd(mdev);
+			drbdd(mdev->tconn);
 			put_net_conf(mdev->tconn);
 		}
 	}
-- 
1.7.4.1


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

* [PATCH 094/118] drbd: Converted drbd_free_sock() and drbd_disconnect() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (92 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 093/118] drbd: Converted drbdd() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 095/118] drbd: Moved the mdev member into drbd_work (from drbd_request and drbd_peer_request) Philipp Reisner
                   ` (25 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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     |   30 +++++++-------
 drivers/block/drbd/drbd_receiver.c |   72 ++++++++++++++++++++---------------
 3 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 70509c5..388dc1d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1164,7 +1164,7 @@ extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 		       unsigned int set_size);
 extern void tl_clear(struct drbd_conf *mdev);
 extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *);
-extern void drbd_free_sock(struct drbd_conf *mdev);
+extern void drbd_free_sock(struct drbd_tconn *tconn);
 extern int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
 		     void *buf, size_t size, unsigned msg_flags);
 extern int drbd_send_protocol(struct drbd_tconn *tconn);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7612394..b427c1a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2443,21 +2443,21 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
 	kfree(ldev);
 }
 
-void drbd_free_sock(struct drbd_conf *mdev)
+void drbd_free_sock(struct drbd_tconn *tconn)
 {
-	if (mdev->tconn->data.socket) {
-		mutex_lock(&mdev->tconn->data.mutex);
-		kernel_sock_shutdown(mdev->tconn->data.socket, SHUT_RDWR);
-		sock_release(mdev->tconn->data.socket);
-		mdev->tconn->data.socket = NULL;
-		mutex_unlock(&mdev->tconn->data.mutex);
+	if (tconn->data.socket) {
+		mutex_lock(&tconn->data.mutex);
+		kernel_sock_shutdown(tconn->data.socket, SHUT_RDWR);
+		sock_release(tconn->data.socket);
+		tconn->data.socket = NULL;
+		mutex_unlock(&tconn->data.mutex);
 	}
-	if (mdev->tconn->meta.socket) {
-		mutex_lock(&mdev->tconn->meta.mutex);
-		kernel_sock_shutdown(mdev->tconn->meta.socket, SHUT_RDWR);
-		sock_release(mdev->tconn->meta.socket);
-		mdev->tconn->meta.socket = NULL;
-		mutex_unlock(&mdev->tconn->meta.mutex);
+	if (tconn->meta.socket) {
+		mutex_lock(&tconn->meta.mutex);
+		kernel_sock_shutdown(tconn->meta.socket, SHUT_RDWR);
+		sock_release(tconn->meta.socket);
+		tconn->meta.socket = NULL;
+		mutex_unlock(&tconn->meta.mutex);
 	}
 }
 
@@ -2475,7 +2475,7 @@ void drbd_free_resources(struct drbd_conf *mdev)
 	crypto_free_hash(mdev->tconn->integrity_r_tfm);
 	mdev->tconn->integrity_r_tfm = NULL;
 
-	drbd_free_sock(mdev);
+	drbd_free_sock(mdev->tconn);
 
 	__no_warn(local,
 		  drbd_free_bc(mdev->ldev);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1d6df7a..c280fa8 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -62,6 +62,7 @@ enum finish_epoch {
 
 static int drbd_do_handshake(struct drbd_tconn *tconn);
 static int drbd_do_auth(struct drbd_tconn *tconn);
+static int drbd_disconnected(int vnr, void *p, void *data);
 
 static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
 static int e_end_block(struct drbd_conf *, struct drbd_work *, int);
@@ -3832,19 +3833,49 @@ void drbd_flush_workqueue(struct drbd_tconn *tconn)
 	wait_for_completion(&barr.done);
 }
 
-static void drbd_disconnect(struct drbd_conf *mdev)
+static void drbd_disconnect(struct drbd_tconn *tconn)
 {
-	enum drbd_fencing_p fp;
 	union drbd_state os, ns;
 	int rv = SS_UNKNOWN_ERROR;
-	unsigned int i;
 
-	if (mdev->state.conn == C_STANDALONE)
+	if (tconn->volume0->state.conn == C_STANDALONE)
 		return;
 
 	/* asender does not clean up anything. it must not interfere, either */
-	drbd_thread_stop(&mdev->tconn->asender);
-	drbd_free_sock(mdev);
+	drbd_thread_stop(&tconn->asender);
+	drbd_free_sock(tconn);
+
+	idr_for_each(&tconn->volumes, drbd_disconnected, tconn);
+
+	conn_info(tconn, "Connection closed\n");
+
+	spin_lock_irq(&tconn->req_lock);
+	os = tconn->volume0->state;
+	if (os.conn >= C_UNCONNECTED) {
+		/* Do not restart in case we are C_DISCONNECTING */
+		ns.i = os.i;
+		ns.conn = C_UNCONNECTED;
+		rv = _drbd_set_state(tconn->volume0, ns, CS_VERBOSE, NULL);
+	}
+	spin_unlock_irq(&tconn->req_lock);
+
+	if (os.conn == C_DISCONNECTING) {
+		wait_event(tconn->net_cnt_wait, atomic_read(&tconn->net_cnt) == 0);
+
+		crypto_free_hash(tconn->cram_hmac_tfm);
+		tconn->cram_hmac_tfm = NULL;
+
+		kfree(tconn->net_conf);
+		tconn->net_conf = NULL;
+		drbd_request_state(tconn->volume0, NS(conn, C_STANDALONE));
+	}
+}
+
+static int drbd_disconnected(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	enum drbd_fencing_p fp;
+	unsigned int i;
 
 	/* wait for current activity to cease. */
 	spin_lock_irq(&mdev->tconn->req_lock);
@@ -3890,8 +3921,6 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	if (!is_susp(mdev->state))
 		tl_clear(mdev);
 
-	dev_info(DEV, "Connection closed\n");
-
 	drbd_md_sync(mdev);
 
 	fp = FP_DONT_CARE;
@@ -3903,27 +3932,6 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	if (mdev->state.role == R_PRIMARY && fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN)
 		drbd_try_outdate_peer_async(mdev);
 
-	spin_lock_irq(&mdev->tconn->req_lock);
-	os = mdev->state;
-	if (os.conn >= C_UNCONNECTED) {
-		/* Do not restart in case we are C_DISCONNECTING */
-		ns = os;
-		ns.conn = C_UNCONNECTED;
-		rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
-	}
-	spin_unlock_irq(&mdev->tconn->req_lock);
-
-	if (os.conn == C_DISCONNECTING) {
-		wait_event(mdev->tconn->net_cnt_wait, atomic_read(&mdev->tconn->net_cnt) == 0);
-
-		crypto_free_hash(mdev->tconn->cram_hmac_tfm);
-		mdev->tconn->cram_hmac_tfm = NULL;
-
-		kfree(mdev->tconn->net_conf);
-		mdev->tconn->net_conf = NULL;
-		drbd_request_state(mdev, NS(conn, C_STANDALONE));
-	}
-
 	/* serialize with bitmap writeout triggered by the state change,
 	 * if any. */
 	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
@@ -3953,6 +3961,8 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 	/* ok, no more ee's on the fly, it is safe to reset the epoch_size */
 	atomic_set(&mdev->current_epoch->epoch_size, 0);
 	D_ASSERT(list_empty(&mdev->current_epoch->list));
+
+	return 0;
 }
 
 /*
@@ -4229,7 +4239,7 @@ int drbdd_init(struct drbd_thread *thi)
 	do {
 		h = drbd_connect(mdev->tconn);
 		if (h == 0) {
-			drbd_disconnect(mdev);
+			drbd_disconnect(mdev->tconn);
 			schedule_timeout_interruptible(HZ);
 		}
 		if (h == -1) {
@@ -4245,7 +4255,7 @@ int drbdd_init(struct drbd_thread *thi)
 		}
 	}
 
-	drbd_disconnect(mdev);
+	drbd_disconnect(mdev->tconn);
 
 	dev_info(DEV, "receiver terminated\n");
 	return 0;
-- 
1.7.4.1


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

* [PATCH 095/118] drbd: Moved the mdev member into drbd_work (from drbd_request and drbd_peer_request)
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (93 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 094/118] drbd: Converted drbd_free_sock() and drbd_disconnect() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 096/118] drbd: Consolidated the setup of the thread name into the framework Philipp Reisner
                   ` (24 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_actlog.c   |    2 ++
 drivers/block/drbd/drbd_int.h      |    5 ++---
 drivers/block/drbd/drbd_main.c     |    8 ++++++++
 drivers/block/drbd/drbd_nl.c       |    6 +++---
 drivers/block/drbd/drbd_receiver.c |   10 ++++++----
 drivers/block/drbd/drbd_req.c      |   11 ++++++-----
 drivers/block/drbd/drbd_req.h      |    4 ++--
 drivers/block/drbd/drbd_state.c    |    1 +
 drivers/block/drbd/drbd_worker.c   |    8 ++++----
 9 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 7943177..637a937 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -228,6 +228,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector)
 		al_work.enr = enr;
 		al_work.old_enr = al_ext->lc_number;
 		al_work.w.cb = w_al_write_transaction;
+		al_work.w.mdev = mdev;
 		drbd_queue_work_front(&mdev->tconn->data.work, &al_work.w);
 		wait_for_completion(&al_work.event);
 
@@ -717,6 +718,7 @@ static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector,
 			if (udw) {
 				udw->enr = ext->lce.lc_number;
 				udw->w.cb = w_update_odbm;
+				udw->w.mdev = mdev;
 				drbd_queue_work_front(&mdev->tconn->data.work, &udw->w);
 			} else {
 				dev_warn(DEV, "Could not kmalloc an udw\n");
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 388dc1d..5be0ae8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -644,13 +644,13 @@ typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel);
 struct drbd_work {
 	struct list_head list;
 	drbd_work_cb cb;
+	struct drbd_conf *mdev;
 };
 
 #include "drbd_interval.h"
 
 struct drbd_request {
 	struct drbd_work w;
-	struct drbd_conf *mdev;
 
 	/* if local IO is not allowed, will be NULL.
 	 * if local IO _is_ allowed, holds the locally submitted bio clone,
@@ -714,7 +714,6 @@ struct digest_info {
 struct drbd_peer_request {
 	struct drbd_work w;
 	struct drbd_epoch *epoch; /* for writes */
-	struct drbd_conf *mdev;
 	struct page *pages;
 	atomic_t pending_bios;
 	struct drbd_interval i;
@@ -1536,7 +1535,7 @@ extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev,
 		struct list_head *head);
 extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled);
 extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed);
-extern void drbd_flush_workqueue(struct drbd_tconn *tconn);
+extern void drbd_flush_workqueue(struct drbd_conf *mdev);
 
 /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to
  * mess with get_fs/set_fs, we know we are KERNEL_DS always. */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b427c1a..b054b7b 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1848,6 +1848,14 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	mdev->md_sync_work.cb = w_md_sync;
 	mdev->bm_io_work.w.cb = w_bitmap_io;
 	mdev->start_resync_work.cb = w_start_resync;
+
+	mdev->resync_work.mdev  = mdev;
+	mdev->unplug_work.mdev  = mdev;
+	mdev->go_diskless.mdev  = mdev;
+	mdev->md_sync_work.mdev = mdev;
+	mdev->bm_io_work.w.mdev = mdev;
+	mdev->start_resync_work.mdev = mdev;
+
 	init_timer(&mdev->resync_timer);
 	init_timer(&mdev->md_sync_timer);
 	init_timer(&mdev->start_resync_timer);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 331495f..0debe58 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -876,7 +876,7 @@ static void drbd_reconfig_start(struct drbd_conf *mdev)
 	wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
 	wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
 	drbd_thread_start(&mdev->tconn->worker);
-	drbd_flush_workqueue(mdev->tconn);
+	drbd_flush_workqueue(mdev);
 }
 
 /* if still unconfigured, stops worker again.
@@ -1076,7 +1076,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 	/* also wait for the last barrier ack. */
 	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt) || is_susp(mdev->state));
 	/* and for any other previously queued work */
-	drbd_flush_workqueue(mdev->tconn);
+	drbd_flush_workqueue(mdev);
 
 	rv = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
 	retcode = rv;  /* FIXME: Type mismatch. */
@@ -1520,7 +1520,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 		}
 	}
 
-	drbd_flush_workqueue(mdev->tconn);
+	drbd_flush_workqueue(mdev);
 	spin_lock_irq(&mdev->tconn->req_lock);
 	if (mdev->tconn->net_conf != NULL) {
 		retcode = ERR_NET_CONFIGURED;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index c280fa8..183e533 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -345,7 +345,7 @@ drbd_alloc_ee(struct drbd_conf *mdev, u64 id, sector_t sector,
 	peer_req->i.waiting = false;
 
 	peer_req->epoch = NULL;
-	peer_req->mdev = mdev;
+	peer_req->w.mdev = mdev;
 	peer_req->pages = page;
 	atomic_set(&peer_req->pending_bios, 0);
 	peer_req->flags = 0;
@@ -3823,13 +3823,14 @@ static void drbdd(struct drbd_tconn *tconn)
 	}
 }
 
-void drbd_flush_workqueue(struct drbd_tconn *tconn)
+void drbd_flush_workqueue(struct drbd_conf *mdev)
 {
 	struct drbd_wq_barrier barr;
 
 	barr.w.cb = w_prev_work_done;
+	barr.w.mdev = mdev;
 	init_completion(&barr.done);
-	drbd_queue_work(&tconn->data.work, &barr.w);
+	drbd_queue_work(&mdev->tconn->data.work, &barr.w);
 	wait_for_completion(&barr.done);
 }
 
@@ -3909,7 +3910,7 @@ static int drbd_disconnected(int vnr, void *p, void *data)
 	/* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
 	 * w_make_resync_request etc. which may still be on the worker queue
 	 * to be "canceled" */
-	drbd_flush_workqueue(mdev->tconn);
+	drbd_flush_workqueue(mdev);
 
 	/* This also does reclaim_net_ee().  If we do this too early, we might
 	 * miss some resync ee and pages.*/
@@ -4510,6 +4511,7 @@ static int got_OVResult(struct drbd_conf *mdev, enum drbd_packet cmd)
 		w = kmalloc(sizeof(*w), GFP_NOIO);
 		if (w) {
 			w->cb = w_ov_finished;
+			w->mdev = mdev;
 			drbd_queue_work_front(&mdev->tconn->data.work, w);
 		} else {
 			dev_err(DEV, "kmalloc(w) failed.");
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 6bcf417..45a543e 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -67,7 +67,7 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
 
 	drbd_req_make_private_bio(req, bio_src);
 	req->rq_state    = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
-	req->mdev        = mdev;
+	req->w.mdev      = mdev;
 	req->master_bio  = bio_src;
 	req->epoch       = 0;
 
@@ -155,6 +155,7 @@ static void queue_barrier(struct drbd_conf *mdev)
 
 	b = mdev->tconn->newest_tle;
 	b->w.cb = w_send_barrier;
+	b->w.mdev = mdev;
 	/* inc_ap_pending done here, so we won't
 	 * get imbalanced on connection loss.
 	 * dec_ap_pending will be done in got_BarrierAck
@@ -192,7 +193,7 @@ void complete_master_bio(struct drbd_conf *mdev,
 static void drbd_remove_request_interval(struct rb_root *root,
 					 struct drbd_request *req)
 {
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	struct drbd_interval *i = &req->i;
 
 	drbd_remove_interval(root, i);
@@ -211,7 +212,7 @@ static void drbd_remove_request_interval(struct rb_root *root,
 void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 {
 	const unsigned long s = req->rq_state;
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	/* only WRITES may end up here without a master bio (on barrier ack) */
 	int rw = req->master_bio ? bio_data_dir(req->master_bio) : WRITE;
 
@@ -294,7 +295,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 
 static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_error *m)
 {
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 
 	if (!is_susp(mdev->state))
 		_req_may_be_done(req, m);
@@ -315,7 +316,7 @@ static void _req_may_be_done_not_susp(struct drbd_request *req, struct bio_and_e
 int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		struct bio_and_error *m)
 {
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	int rv = 0;
 	m->bio = NULL;
 
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 431e3f9..e6232ce 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -255,7 +255,7 @@ extern void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
  * outside the spinlock, e.g. when walking some list on cleanup. */
 static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
 {
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	struct bio_and_error m;
 	int rv;
 
@@ -275,7 +275,7 @@ static inline int req_mod(struct drbd_request *req,
 		enum drbd_req_event what)
 {
 	unsigned long flags;
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	struct bio_and_error m;
 	int rv;
 
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 38d330b..3667984 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -843,6 +843,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 		ascw->ns = ns;
 		ascw->flags = flags;
 		ascw->w.cb = w_after_state_ch;
+		ascw->w.mdev = mdev;
 		ascw->done = done;
 		drbd_queue_work(&mdev->tconn->data.work, &ascw->w);
 	} else {
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 16db1f4..cac65f6 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -83,7 +83,7 @@ void drbd_md_io_complete(struct bio *bio, int error)
 void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
 {
 	unsigned long flags = 0;
-	struct drbd_conf *mdev = peer_req->mdev;
+	struct drbd_conf *mdev = peer_req->w.mdev;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	mdev->read_cnt += peer_req->i.size >> 9;
@@ -103,7 +103,7 @@ void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(lo
 static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
 {
 	unsigned long flags = 0;
-	struct drbd_conf *mdev = peer_req->mdev;
+	struct drbd_conf *mdev = peer_req->w.mdev;
 	sector_t e_sector;
 	int do_wake;
 	u64 block_id;
@@ -155,7 +155,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
 void drbd_endio_sec(struct bio *bio, int error)
 {
 	struct drbd_peer_request *peer_req = bio->bi_private;
-	struct drbd_conf *mdev = peer_req->mdev;
+	struct drbd_conf *mdev = peer_req->w.mdev;
 	int uptodate = bio_flagged(bio, BIO_UPTODATE);
 	int is_write = bio_data_dir(bio) == WRITE;
 
@@ -192,7 +192,7 @@ void drbd_endio_pri(struct bio *bio, int error)
 {
 	unsigned long flags;
 	struct drbd_request *req = bio->bi_private;
-	struct drbd_conf *mdev = req->mdev;
+	struct drbd_conf *mdev = req->w.mdev;
 	struct bio_and_error m;
 	enum drbd_req_event what;
 	int uptodate = bio_flagged(bio, BIO_UPTODATE);
-- 
1.7.4.1


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

* [PATCH 096/118] drbd: Consolidated the setup of the thread name into the framework
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (94 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 095/118] drbd: Moved the mdev member into drbd_work (from drbd_request and drbd_peer_request) Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 097/118] drbd: Converted drbdd_init() from mdev to tconn Philipp Reisner
                   ` (23 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b054b7b..4589be4 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -458,6 +458,9 @@ static int drbd_thread_setup(void *arg)
 	unsigned long flags;
 	int retval;
 
+	snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s",
+		 thi->name[0], thi->mdev->tconn->name);
+
 restart:
 	retval = thi->function(thi);
 
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 183e533..3fcc8dc 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4230,11 +4230,8 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 int drbdd_init(struct drbd_thread *thi)
 {
 	struct drbd_conf *mdev = thi->mdev;
-	unsigned int minor = mdev_to_minor(mdev);
 	int h;
 
-	sprintf(current->comm, "drbd%d_receiver", minor);
-
 	dev_info(DEV, "receiver (re)started\n");
 
 	do {
@@ -4575,8 +4572,6 @@ int drbd_asender(struct drbd_thread *thi)
 	int ping_timeout_active = 0;
 	int empty;
 
-	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
-
 	current->policy = SCHED_RR;  /* Make this a realtime task! */
 	current->rt_priority = 2;    /* more important than all other tasks */
 
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index cac65f6..6f70962 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1631,8 +1631,6 @@ int drbd_worker(struct drbd_thread *thi)
 	LIST_HEAD(work_list);
 	int intr = 0, i;
 
-	sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev));
-
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(thi);
 
-- 
1.7.4.1


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

* [PATCH 097/118] drbd: Converted drbdd_init() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (95 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 096/118] drbd: Consolidated the setup of the thread name into the framework Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 098/118] drbd: Converted drbd_asender() " Philipp Reisner
                   ` (22 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 3fcc8dc..cc5e937 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4229,33 +4229,33 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 
 int drbdd_init(struct drbd_thread *thi)
 {
-	struct drbd_conf *mdev = thi->mdev;
+	struct drbd_tconn *tconn = thi->mdev->tconn;
 	int h;
 
-	dev_info(DEV, "receiver (re)started\n");
+	conn_info(tconn, "receiver (re)started\n");
 
 	do {
-		h = drbd_connect(mdev->tconn);
+		h = drbd_connect(tconn);
 		if (h == 0) {
-			drbd_disconnect(mdev->tconn);
+			drbd_disconnect(tconn);
 			schedule_timeout_interruptible(HZ);
 		}
 		if (h == -1) {
-			dev_warn(DEV, "Discarding network configuration.\n");
-			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			conn_warn(tconn, "Discarding network configuration.\n");
+			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
 		}
 	} while (h == 0);
 
 	if (h > 0) {
-		if (get_net_conf(mdev->tconn)) {
-			drbdd(mdev->tconn);
-			put_net_conf(mdev->tconn);
+		if (get_net_conf(tconn)) {
+			drbdd(tconn);
+			put_net_conf(tconn);
 		}
 	}
 
-	drbd_disconnect(mdev->tconn);
+	drbd_disconnect(tconn);
 
-	dev_info(DEV, "receiver terminated\n");
+	conn_info(tconn, "receiver terminated\n");
 	return 0;
 }
 
-- 
1.7.4.1


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

* [PATCH 098/118] drbd: Converted drbd_asender() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (96 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 097/118] drbd: Converted drbdd_init() from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 099/118] drbd: Converted drbd_worker() " Philipp Reisner
                   ` (21 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index cc5e937..3434ca9 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -392,9 +392,7 @@ int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
 }
 
 
-/*
- * This function is called from _asender only_
- * but see also comments in _req_mod(,BARRIER_ACKED)
+/* See also comments in _req_mod(,BARRIER_ACKED)
  * and receive_Barrier.
  *
  * Move entries from net_ee to done_ee, if ready.
@@ -4558,66 +4556,85 @@ static struct asender_cmd *get_asender_cmd(int cmd)
 	return &asender_tbl[cmd];
 }
 
+static int _drbd_process_done_ee(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	return !drbd_process_done_ee(mdev);
+}
+
+static int _check_ee_empty(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	struct drbd_tconn *tconn = mdev->tconn;
+	int not_empty;
+
+	spin_lock_irq(&tconn->req_lock);
+	not_empty = !list_empty(&mdev->done_ee);
+	spin_unlock_irq(&tconn->req_lock);
+
+	return not_empty;
+}
+
+static int tconn_process_done_ee(struct drbd_tconn *tconn)
+{
+	int not_empty, err;
+
+	do {
+		clear_bit(SIGNAL_ASENDER, &tconn->flags);
+		flush_signals(current);
+		err = idr_for_each(&tconn->volumes, _drbd_process_done_ee, NULL);
+		if (err)
+			return err;
+		set_bit(SIGNAL_ASENDER, &tconn->flags);
+		not_empty = idr_for_each(&tconn->volumes, _check_ee_empty, NULL);
+	} while (not_empty);
+
+	return 0;
+}
+
 int drbd_asender(struct drbd_thread *thi)
 {
-	struct drbd_conf *mdev = thi->mdev;
-	struct p_header *h = &mdev->tconn->meta.rbuf.header;
+	struct drbd_tconn *tconn = thi->mdev->tconn;
+	struct p_header *h = &tconn->meta.rbuf.header;
 	struct asender_cmd *cmd = NULL;
 	struct packet_info pi;
-
 	int rv;
 	void *buf    = h;
 	int received = 0;
 	int expect   = sizeof(struct p_header);
 	int ping_timeout_active = 0;
-	int empty;
 
 	current->policy = SCHED_RR;  /* Make this a realtime task! */
 	current->rt_priority = 2;    /* more important than all other tasks */
 
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(thi);
-		if (test_and_clear_bit(SEND_PING, &mdev->tconn->flags)) {
-			if (!drbd_send_ping(mdev)) {
-				dev_err(DEV, "drbd_send_ping has failed\n");
+		if (test_and_clear_bit(SEND_PING, &tconn->flags)) {
+			if (!drbd_send_ping(tconn->volume0)) {
+				conn_err(tconn, "drbd_send_ping has failed\n");
 				goto reconnect;
 			}
-			mdev->tconn->meta.socket->sk->sk_rcvtimeo =
-				mdev->tconn->net_conf->ping_timeo*HZ/10;
+			tconn->meta.socket->sk->sk_rcvtimeo =
+				tconn->net_conf->ping_timeo*HZ/10;
 			ping_timeout_active = 1;
 		}
 
-		/* conditionally cork;
-		 * it may hurt latency if we cork without much to send */
-		if (!mdev->tconn->net_conf->no_cork &&
-			3 < atomic_read(&mdev->unacked_cnt))
-			drbd_tcp_cork(mdev->tconn->meta.socket);
-		while (1) {
-			clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
-			flush_signals(current);
-			if (!drbd_process_done_ee(mdev))
-				goto reconnect;
-			/* to avoid race with newly queued ACKs */
-			set_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
-			spin_lock_irq(&mdev->tconn->req_lock);
-			empty = list_empty(&mdev->done_ee);
-			spin_unlock_irq(&mdev->tconn->req_lock);
-			/* new ack may have been queued right here,
-			 * but then there is also a signal pending,
-			 * and we start over... */
-			if (empty)
-				break;
-		}
+		/* TODO: conditionally cork; it may hurt latency if we cork without
+		   much to send */
+		if (!tconn->net_conf->no_cork)
+			drbd_tcp_cork(tconn->meta.socket);
+		if (tconn_process_done_ee(tconn))
+			goto reconnect;
 		/* but unconditionally uncork unless disabled */
-		if (!mdev->tconn->net_conf->no_cork)
-			drbd_tcp_uncork(mdev->tconn->meta.socket);
+		if (!tconn->net_conf->no_cork)
+			drbd_tcp_uncork(tconn->meta.socket);
 
 		/* short circuit, recv_msg would return EINTR anyways. */
 		if (signal_pending(current))
 			continue;
 
-		rv = drbd_recv_short(mdev->tconn->meta.socket, buf, expect-received, 0);
-		clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
+		rv = drbd_recv_short(tconn->meta.socket, buf, expect-received, 0);
+		clear_bit(SIGNAL_ASENDER, &tconn->flags);
 
 		flush_signals(current);
 
@@ -4635,47 +4652,46 @@ int drbd_asender(struct drbd_thread *thi)
 			received += rv;
 			buf	 += rv;
 		} else if (rv == 0) {
-			dev_err(DEV, "meta connection shut down by peer.\n");
+			conn_err(tconn, "meta connection shut down by peer.\n");
 			goto reconnect;
 		} else if (rv == -EAGAIN) {
 			/* If the data socket received something meanwhile,
 			 * that is good enough: peer is still alive. */
-			if (time_after(mdev->tconn->last_received,
-				jiffies - mdev->tconn->meta.socket->sk->sk_rcvtimeo))
+			if (time_after(tconn->last_received,
+				jiffies - tconn->meta.socket->sk->sk_rcvtimeo))
 				continue;
 			if (ping_timeout_active) {
-				dev_err(DEV, "PingAck did not arrive in time.\n");
+				conn_err(tconn, "PingAck did not arrive in time.\n");
 				goto reconnect;
 			}
-			set_bit(SEND_PING, &mdev->tconn->flags);
+			set_bit(SEND_PING, &tconn->flags);
 			continue;
 		} else if (rv == -EINTR) {
 			continue;
 		} else {
-			dev_err(DEV, "sock_recvmsg returned %d\n", rv);
+			conn_err(tconn, "sock_recvmsg returned %d\n", rv);
 			goto reconnect;
 		}
 
 		if (received == expect && cmd == NULL) {
-			if (!decode_header(mdev->tconn, h, &pi))
+			if (!decode_header(tconn, h, &pi))
 				goto reconnect;
 			cmd = get_asender_cmd(pi.cmd);
 			if (unlikely(cmd == NULL)) {
-				dev_err(DEV, "unknown command %d on meta (l: %d)\n",
+				conn_err(tconn, "unknown command %d on meta (l: %d)\n",
 					pi.cmd, pi.size);
 				goto disconnect;
 			}
 			expect = cmd->pkt_size;
 			if (pi.size != expect - sizeof(struct p_header)) {
-				dev_err(DEV, "Wrong packet size on meta (c: %d, l: %d)\n",
+				conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n",
 					pi.cmd, pi.size);
 				goto reconnect;
 			}
 		}
 		if (received == expect) {
-			mdev->tconn->last_received = jiffies;
-			D_ASSERT(cmd != NULL);
-			if (!cmd->process(mdev, pi.cmd))
+			tconn->last_received = jiffies;
+			if (!cmd->process(vnr_to_mdev(tconn, pi.vnr), pi.cmd))
 				goto reconnect;
 
 			/* the idle_timeout (ping-int)
@@ -4692,18 +4708,15 @@ int drbd_asender(struct drbd_thread *thi)
 
 	if (0) {
 reconnect:
-		drbd_force_state(mdev, NS(conn, C_NETWORK_FAILURE));
-		drbd_md_sync(mdev);
+		drbd_force_state(tconn->volume0, NS(conn, C_NETWORK_FAILURE));
 	}
 	if (0) {
 disconnect:
-		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
-		drbd_md_sync(mdev);
+		drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
 	}
-	clear_bit(SIGNAL_ASENDER, &mdev->tconn->flags);
+	clear_bit(SIGNAL_ASENDER, &tconn->flags);
 
-	D_ASSERT(mdev->state.conn < C_CONNECTED);
-	dev_info(DEV, "asender terminated\n");
+	conn_info(tconn, "asender terminated\n");
 
 	return 0;
 }
-- 
1.7.4.1


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

* [PATCH 099/118] drbd: Converted drbd_worker() from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (97 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 098/118] drbd: Converted drbd_asender() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 100/118] drbd: drbd_thread has now a pointer to a tconn instead of to a mdev Philipp Reisner
                   ` (20 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_worker.c |   97 ++++++++++++++++++++------------------
 1 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 6f70962..c9b10d6 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1624,35 +1624,53 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 	drbd_state_unlock(mdev);
 }
 
+static int _worker_dying(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+
+	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
+	/* _drbd_set_state only uses stop_nowait.
+	 * wait here for the exiting receiver. */
+	drbd_thread_stop(&mdev->tconn->receiver);
+	drbd_mdev_cleanup(mdev);
+
+	clear_bit(DEVICE_DYING, &mdev->flags);
+	clear_bit(CONFIG_PENDING, &mdev->flags);
+	wake_up(&mdev->state_wait);
+
+	return 0;
+}
+
 int drbd_worker(struct drbd_thread *thi)
 {
-	struct drbd_conf *mdev = thi->mdev;
+	struct drbd_tconn *tconn = thi->mdev->tconn;
 	struct drbd_work *w = NULL;
 	LIST_HEAD(work_list);
-	int intr = 0, i;
+	int intr = 0;
 
 	while (get_t_state(thi) == RUNNING) {
 		drbd_thread_current_set_cpu(thi);
 
-		if (down_trylock(&mdev->tconn->data.work.s)) {
-			mutex_lock(&mdev->tconn->data.mutex);
-			if (mdev->tconn->data.socket && !mdev->tconn->net_conf->no_cork)
-				drbd_tcp_uncork(mdev->tconn->data.socket);
-			mutex_unlock(&mdev->tconn->data.mutex);
+		if (down_trylock(&tconn->data.work.s)) {
+			mutex_lock(&tconn->data.mutex);
+			if (tconn->data.socket && !tconn->net_conf->no_cork)
+				drbd_tcp_uncork(tconn->data.socket);
+			mutex_unlock(&tconn->data.mutex);
 
-			intr = down_interruptible(&mdev->tconn->data.work.s);
+			intr = down_interruptible(&tconn->data.work.s);
 
-			mutex_lock(&mdev->tconn->data.mutex);
-			if (mdev->tconn->data.socket  && !mdev->tconn->net_conf->no_cork)
-				drbd_tcp_cork(mdev->tconn->data.socket);
-			mutex_unlock(&mdev->tconn->data.mutex);
+			mutex_lock(&tconn->data.mutex);
+			if (tconn->data.socket  && !tconn->net_conf->no_cork)
+				drbd_tcp_cork(tconn->data.socket);
+			mutex_unlock(&tconn->data.mutex);
 		}
 
 		if (intr) {
-			D_ASSERT(intr == -EINTR);
 			flush_signals(current);
-			if (!expect(get_t_state(thi) != RUNNING))
+			if (get_t_state(thi) == RUNNING) {
+				conn_warn(tconn, "Worker got an unexpected signal\n");
 				continue;
+			}
 			break;
 		}
 
@@ -1663,8 +1681,8 @@ int drbd_worker(struct drbd_thread *thi)
 		   this...   */
 
 		w = NULL;
-		spin_lock_irq(&mdev->tconn->data.work.q_lock);
-		if (!expect(!list_empty(&mdev->tconn->data.work.q))) {
+		spin_lock_irq(&tconn->data.work.q_lock);
+		if (list_empty(&tconn->data.work.q)) {
 			/* something terribly wrong in our logic.
 			 * we were able to down() the semaphore,
 			 * but the list is empty... doh.
@@ -1676,57 +1694,44 @@ int drbd_worker(struct drbd_thread *thi)
 			 *
 			 * I'll try to get away just starting over this loop.
 			 */
-			spin_unlock_irq(&mdev->tconn->data.work.q_lock);
+			conn_warn(tconn, "Work list unexpectedly empty\n");
+			spin_unlock_irq(&tconn->data.work.q_lock);
 			continue;
 		}
-		w = list_entry(mdev->tconn->data.work.q.next, struct drbd_work, list);
+		w = list_entry(tconn->data.work.q.next, struct drbd_work, list);
 		list_del_init(&w->list);
-		spin_unlock_irq(&mdev->tconn->data.work.q_lock);
+		spin_unlock_irq(&tconn->data.work.q_lock);
 
-		if (!w->cb(mdev, w, mdev->state.conn < C_CONNECTED)) {
+		if (!w->cb(w->mdev, w, tconn->volume0->state.conn < C_CONNECTED)) {
 			/* dev_warn(DEV, "worker: a callback failed! \n"); */
-			if (mdev->state.conn >= C_CONNECTED)
-				drbd_force_state(mdev,
-						NS(conn, C_NETWORK_FAILURE));
+			if (tconn->volume0->state.conn >= C_CONNECTED)
+				drbd_force_state(tconn->volume0,
+						 NS(conn, C_NETWORK_FAILURE));
 		}
 	}
-	D_ASSERT(test_bit(DEVICE_DYING, &mdev->flags));
-	D_ASSERT(test_bit(CONFIG_PENDING, &mdev->flags));
 
-	spin_lock_irq(&mdev->tconn->data.work.q_lock);
-	i = 0;
-	while (!list_empty(&mdev->tconn->data.work.q)) {
-		list_splice_init(&mdev->tconn->data.work.q, &work_list);
-		spin_unlock_irq(&mdev->tconn->data.work.q_lock);
+	spin_lock_irq(&tconn->data.work.q_lock);
+	while (!list_empty(&tconn->data.work.q)) {
+		list_splice_init(&tconn->data.work.q, &work_list);
+		spin_unlock_irq(&tconn->data.work.q_lock);
 
 		while (!list_empty(&work_list)) {
 			w = list_entry(work_list.next, struct drbd_work, list);
 			list_del_init(&w->list);
-			w->cb(mdev, w, 1);
-			i++; /* dead debugging code */
+			w->cb(w->mdev, w, 1);
 		}
 
-		spin_lock_irq(&mdev->tconn->data.work.q_lock);
+		spin_lock_irq(&tconn->data.work.q_lock);
 	}
-	sema_init(&mdev->tconn->data.work.s, 0);
+	sema_init(&tconn->data.work.s, 0);
 	/* DANGEROUS race: if someone did queue his work within the spinlock,
 	 * but up() ed outside the spinlock, we could get an up() on the
 	 * semaphore without corresponding list entry.
 	 * So don't do that.
 	 */
-	spin_unlock_irq(&mdev->tconn->data.work.q_lock);
+	spin_unlock_irq(&tconn->data.work.q_lock);
 
-	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
-	/* _drbd_set_state only uses stop_nowait.
-	 * wait here for the exiting receiver. */
-	drbd_thread_stop(&mdev->tconn->receiver);
-	drbd_mdev_cleanup(mdev);
-
-	dev_info(DEV, "worker terminated\n");
-
-	clear_bit(DEVICE_DYING, &mdev->flags);
-	clear_bit(CONFIG_PENDING, &mdev->flags);
-	wake_up(&mdev->state_wait);
+	idr_for_each(&tconn->volumes, _worker_dying, NULL);
 
 	return 0;
 }
-- 
1.7.4.1


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

* [PATCH 100/118] drbd: drbd_thread has now a pointer to a tconn instead of to a mdev
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (98 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 099/118] drbd: Converted drbd_worker() " Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 101/118] drbd: Moved some initializing code into drbd_new_tconn() Philipp Reisner
                   ` (19 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index e85221f..e8d652f 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -119,9 +119,9 @@ static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
 	if (!__ratelimit(&drbd_ratelimit_state))
 		return;
 	dev_err(DEV, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
-		drbd_task_to_thread_name(mdev, current),
+		drbd_task_to_thread_name(mdev->tconn, current),
 		func, b->bm_why ?: "?",
-		drbd_task_to_thread_name(mdev, b->bm_task));
+		drbd_task_to_thread_name(mdev->tconn, b->bm_task));
 }
 
 void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
@@ -138,9 +138,9 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why, enum bm_flag flags)
 
 	if (trylock_failed) {
 		dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
-			 drbd_task_to_thread_name(mdev, current),
+			 drbd_task_to_thread_name(mdev->tconn, current),
 			 why, b->bm_why ?: "?",
-			 drbd_task_to_thread_name(mdev, b->bm_task));
+			 drbd_task_to_thread_name(mdev->tconn, b->bm_task));
 		mutex_lock(&b->bm_change);
 	}
 	if (BM_LOCKED_MASK & b->bm_flags)
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 5be0ae8..ddbb3d2 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -624,7 +624,7 @@ struct drbd_thread {
 	struct completion stop;
 	enum drbd_thread_state t_state;
 	int (*function) (struct drbd_thread *);
-	struct drbd_conf *mdev;
+	struct drbd_tconn *tconn;
 	int reset_cpu_mask;
 	char name[9];
 };
@@ -1150,7 +1150,7 @@ enum dds_flags {
 extern void drbd_init_set_defaults(struct drbd_conf *mdev);
 extern int  drbd_thread_start(struct drbd_thread *thi);
 extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
-extern char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task);
+extern char *drbd_task_to_thread_name(struct drbd_tconn *tconn, struct task_struct *task);
 #ifdef CONFIG_SMP
 extern void drbd_thread_current_set_cpu(struct drbd_thread *thi);
 extern void drbd_calc_cpu_mask(struct drbd_tconn *tconn);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 4589be4..dca4832 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -454,12 +454,12 @@ void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 static int drbd_thread_setup(void *arg)
 {
 	struct drbd_thread *thi = (struct drbd_thread *) arg;
-	struct drbd_conf *mdev = thi->mdev;
+	struct drbd_tconn *tconn = thi->tconn;
 	unsigned long flags;
 	int retval;
 
 	snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s",
-		 thi->name[0], thi->mdev->tconn->name);
+		 thi->name[0], thi->tconn->name);
 
 restart:
 	retval = thi->function(thi);
@@ -477,7 +477,7 @@ restart:
 	 */
 
 	if (thi->t_state == RESTARTING) {
-		dev_info(DEV, "Restarting %s thread\n", thi->name);
+		conn_info(tconn, "Restarting %s thread\n", thi->name);
 		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		goto restart;
@@ -489,27 +489,27 @@ restart:
 	complete(&thi->stop);
 	spin_unlock_irqrestore(&thi->t_lock, flags);
 
-	dev_info(DEV, "Terminating %s\n", current->comm);
+	conn_info(tconn, "Terminating %s\n", current->comm);
 
 	/* Release mod reference taken when thread was started */
 	module_put(THIS_MODULE);
 	return retval;
 }
 
-static void drbd_thread_init(struct drbd_conf *mdev, struct drbd_thread *thi,
+static void drbd_thread_init(struct drbd_tconn *tconn, struct drbd_thread *thi,
 			     int (*func) (struct drbd_thread *), char *name)
 {
 	spin_lock_init(&thi->t_lock);
 	thi->task    = NULL;
 	thi->t_state = NONE;
 	thi->function = func;
-	thi->mdev = mdev;
+	thi->tconn = tconn;
 	strncpy(thi->name, name, ARRAY_SIZE(thi->name));
 }
 
 int drbd_thread_start(struct drbd_thread *thi)
 {
-	struct drbd_conf *mdev = thi->mdev;
+	struct drbd_tconn *tconn = thi->tconn;
 	struct task_struct *nt;
 	unsigned long flags;
 
@@ -519,28 +519,27 @@ int drbd_thread_start(struct drbd_thread *thi)
 
 	switch (thi->t_state) {
 	case NONE:
-		dev_info(DEV, "Starting %s thread (from %s [%d])\n",
+		conn_info(tconn, "Starting %s thread (from %s [%d])\n",
 			 thi->name, current->comm, current->pid);
 
 		/* Get ref on module for thread - this is released when thread exits */
 		if (!try_module_get(THIS_MODULE)) {
-			dev_err(DEV, "Failed to get module reference in drbd_thread_start\n");
+			conn_err(tconn, "Failed to get module reference in drbd_thread_start\n");
 			spin_unlock_irqrestore(&thi->t_lock, flags);
 			return false;
 		}
 
 		init_completion(&thi->stop);
-		D_ASSERT(thi->task == NULL);
 		thi->reset_cpu_mask = 1;
 		thi->t_state = RUNNING;
 		spin_unlock_irqrestore(&thi->t_lock, flags);
 		flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
 
 		nt = kthread_create(drbd_thread_setup, (void *) thi,
-				    "drbd%d_%s", mdev_to_minor(mdev), thi->name);
+				    "drbd_%c_%s", thi->name[0], thi->tconn->name);
 
 		if (IS_ERR(nt)) {
-			dev_err(DEV, "Couldn't start thread\n");
+			conn_err(tconn, "Couldn't start thread\n");
 
 			module_put(THIS_MODULE);
 			return false;
@@ -553,7 +552,7 @@ int drbd_thread_start(struct drbd_thread *thi)
 		break;
 	case EXITING:
 		thi->t_state = RESTARTING;
-		dev_info(DEV, "Restarting %s thread (from %s [%d])\n",
+		conn_info(tconn, "Restarting %s thread (from %s [%d])\n",
 				thi->name, current->comm, current->pid);
 		/* fall through */
 	case RUNNING:
@@ -594,7 +593,6 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
 		init_completion(&thi->stop);
 		if (thi->task != current)
 			force_sig(DRBD_SIGKILL, thi->task);
-
 	}
 
 	spin_unlock_irqrestore(&thi->t_lock, flags);
@@ -603,9 +601,8 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
 		wait_for_completion(&thi->stop);
 }
 
-static struct drbd_thread *drbd_task_to_thread(struct drbd_conf *mdev, struct task_struct *task)
+static struct drbd_thread *drbd_task_to_thread(struct drbd_tconn *tconn, struct task_struct *task)
 {
-	struct drbd_tconn *tconn = mdev->tconn;
 	struct drbd_thread *thi =
 		task == tconn->receiver.task ? &tconn->receiver :
 		task == tconn->asender.task  ? &tconn->asender :
@@ -614,9 +611,9 @@ static struct drbd_thread *drbd_task_to_thread(struct drbd_conf *mdev, struct ta
 	return thi;
 }
 
-char *drbd_task_to_thread_name(struct drbd_conf *mdev, struct task_struct *task)
+char *drbd_task_to_thread_name(struct drbd_tconn *tconn, struct task_struct *task)
 {
-	struct drbd_thread *thi = drbd_task_to_thread(mdev, task);
+	struct drbd_thread *thi = drbd_task_to_thread(tconn, task);
 	return thi ? thi->name : task->comm;
 }
 
@@ -668,7 +665,7 @@ void drbd_thread_current_set_cpu(struct drbd_thread *thi)
 	if (!thi->reset_cpu_mask)
 		return;
 	thi->reset_cpu_mask = 0;
-	set_cpus_allowed_ptr(p, thi->mdev->tconn->cpu_mask);
+	set_cpus_allowed_ptr(p, thi->tconn->cpu_mask);
 }
 #endif
 
@@ -1878,10 +1875,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	init_waitqueue_head(&mdev->al_wait);
 	init_waitqueue_head(&mdev->seq_wait);
 
-	drbd_thread_init(mdev, &mdev->tconn->receiver, drbdd_init, "receiver");
-	drbd_thread_init(mdev, &mdev->tconn->worker, drbd_worker, "worker");
-	drbd_thread_init(mdev, &mdev->tconn->asender, drbd_asender, "asender");
-
 	/* mdev->tconn->agreed_pro_version gets initialized in drbd_connect() */
 	mdev->write_ordering = WO_bdev_flush;
 	mdev->resync_wenr = LC_FREE;
@@ -2214,6 +2207,10 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 	init_waitqueue_head(&tconn->net_cnt_wait);
 	idr_init(&tconn->volumes);
 
+	drbd_thread_init(tconn, &tconn->receiver, drbdd_init, "receiver");
+	drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
+	drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
+
 	write_lock_irq(&global_state_lock);
 	list_add(&tconn->all_tconn, &drbd_tconns);
 	write_unlock_irq(&global_state_lock);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 3434ca9..54eb53f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4227,7 +4227,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn)
 
 int drbdd_init(struct drbd_thread *thi)
 {
-	struct drbd_tconn *tconn = thi->mdev->tconn;
+	struct drbd_tconn *tconn = thi->tconn;
 	int h;
 
 	conn_info(tconn, "receiver (re)started\n");
@@ -4594,7 +4594,7 @@ static int tconn_process_done_ee(struct drbd_tconn *tconn)
 
 int drbd_asender(struct drbd_thread *thi)
 {
-	struct drbd_tconn *tconn = thi->mdev->tconn;
+	struct drbd_tconn *tconn = thi->tconn;
 	struct p_header *h = &tconn->meta.rbuf.header;
 	struct asender_cmd *cmd = NULL;
 	struct packet_info pi;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index c9b10d6..3f0f84a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1643,7 +1643,7 @@ static int _worker_dying(int vnr, void *p, void *data)
 
 int drbd_worker(struct drbd_thread *thi)
 {
-	struct drbd_tconn *tconn = thi->mdev->tconn;
+	struct drbd_tconn *tconn = thi->tconn;
 	struct drbd_work *w = NULL;
 	LIST_HEAD(work_list);
 	int intr = 0;
-- 
1.7.4.1


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

* [PATCH 101/118] drbd: Moved some initializing code into drbd_new_tconn()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (99 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 100/118] drbd: drbd_thread has now a pointer to a tconn instead of to a mdev Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 102/118] drbd: Generalized the work callbacks Philipp Reisner
                   ` (18 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index dca4832..8f04fd0 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1813,17 +1813,9 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	atomic_set(&mdev->ap_in_flight, 0);
 
 	mutex_init(&mdev->md_io_mutex);
-	mutex_init(&mdev->tconn->data.mutex);
-	mutex_init(&mdev->tconn->meta.mutex);
-	sema_init(&mdev->tconn->data.work.s, 0);
-	sema_init(&mdev->tconn->meta.work.s, 0);
 	mutex_init(&mdev->state_mutex);
 
-	spin_lock_init(&mdev->tconn->data.work.q_lock);
-	spin_lock_init(&mdev->tconn->meta.work.q_lock);
-
 	spin_lock_init(&mdev->al_lock);
-	spin_lock_init(&mdev->tconn->req_lock);
 	spin_lock_init(&mdev->peer_seq_lock);
 	spin_lock_init(&mdev->epoch_lock);
 
@@ -1833,8 +1825,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	INIT_LIST_HEAD(&mdev->read_ee);
 	INIT_LIST_HEAD(&mdev->net_ee);
 	INIT_LIST_HEAD(&mdev->resync_reads);
-	INIT_LIST_HEAD(&mdev->tconn->data.work.q);
-	INIT_LIST_HEAD(&mdev->tconn->meta.work.q);
 	INIT_LIST_HEAD(&mdev->resync_work.list);
 	INIT_LIST_HEAD(&mdev->unplug_work.list);
 	INIT_LIST_HEAD(&mdev->go_diskless.list);
@@ -2191,6 +2181,13 @@ out:
 	return r;
 }
 
+static void drbd_init_workqueue(struct drbd_work_queue* wq)
+{
+	sema_init(&wq->s, 0);
+	spin_lock_init(&wq->q_lock);
+	INIT_LIST_HEAD(&wq->q);
+}
+
 struct drbd_tconn *drbd_new_tconn(char *name)
 {
 	struct drbd_tconn *tconn;
@@ -2203,10 +2200,17 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 	if (!tconn->name)
 		goto fail;
 
+	spin_lock_init(&tconn->req_lock);
 	atomic_set(&tconn->net_cnt, 0);
 	init_waitqueue_head(&tconn->net_cnt_wait);
 	idr_init(&tconn->volumes);
 
+	drbd_init_workqueue(&tconn->data.work);
+	mutex_init(&tconn->data.mutex);
+
+	drbd_init_workqueue(&tconn->meta.work);
+	mutex_init(&tconn->meta.mutex);
+
 	drbd_thread_init(tconn, &tconn->receiver, drbdd_init, "receiver");
 	drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
 	drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
-- 
1.7.4.1


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

* [PATCH 102/118] drbd: Generalized the work callbacks
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (100 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 101/118] drbd: Moved some initializing code into drbd_new_tconn() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 103/118] drbd: Converted drbd_send_ping() and related functions from mdev to tconn Philipp Reisner
                   ` (17 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

No longer work callbacks must operate on a mdev. From now on they
can also operate on a tconn.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_actlog.c   |    8 ++-
 drivers/block/drbd/drbd_int.h      |   45 ++++++++++---------
 drivers/block/drbd/drbd_main.c     |   17 +++++---
 drivers/block/drbd/drbd_receiver.c |   13 ++++--
 drivers/block/drbd/drbd_state.c    |    5 +-
 drivers/block/drbd/drbd_worker.c   |   82 +++++++++++++++++++++--------------
 6 files changed, 100 insertions(+), 70 deletions(-)

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 637a937..0748871 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -63,7 +63,7 @@ struct drbd_atodb_wait {
 };
 
 
-int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int);
+int w_al_write_transaction(struct drbd_work *, int);
 
 static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
 				 struct drbd_backing_dev *bdev,
@@ -291,9 +291,10 @@ static unsigned int rs_extent_to_bm_page(unsigned int rs_enr)
 }
 
 int
-w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+w_al_write_transaction(struct drbd_work *w, int unused)
 {
 	struct update_al_work *aw = container_of(w, struct update_al_work, w);
+	struct drbd_conf *mdev = w->mdev;
 	struct lc_element *updated = aw->al_ext;
 	const unsigned int new_enr = aw->enr;
 	const unsigned int evicted = aw->old_enr;
@@ -612,9 +613,10 @@ void drbd_al_shrink(struct drbd_conf *mdev)
 	wake_up(&mdev->al_wait);
 }
 
-static int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int w_update_odbm(struct drbd_work *w, int unused)
 {
 	struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
+	struct drbd_conf *mdev = w->mdev;
 
 	if (!get_ldev(mdev)) {
 		if (__ratelimit(&drbd_ratelimit_state))
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ddbb3d2..12f0c5e 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -640,11 +640,14 @@ static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
 }
 
 struct drbd_work;
-typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel);
+typedef int (*drbd_work_cb)(struct drbd_work *, int cancel);
 struct drbd_work {
 	struct list_head list;
 	drbd_work_cb cb;
-	struct drbd_conf *mdev;
+	union {
+		struct drbd_conf *mdev;
+		struct drbd_tconn *tconn;
+	};
 };
 
 #include "drbd_interval.h"
@@ -1494,25 +1497,25 @@ extern void drbd_csum_bio(struct drbd_conf *, struct crypto_hash *, struct bio *
 extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *,
 			 struct drbd_peer_request *, void *);
 /* worker callbacks */
-extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int);
-extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_end_data_req(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_end_rsdata_req(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_end_csum_rs_req(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_end_ov_reply(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int);
-extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int);
-extern int w_resync_timer(struct drbd_conf *, struct drbd_work *, int);
-extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int);
-extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int);
-extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int);
-extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int);
-extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int);
-extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int);
-extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int);
-extern int w_restart_disk_io(struct drbd_conf *, struct drbd_work *, int);
-extern int w_send_oos(struct drbd_conf *, struct drbd_work *, int);
-extern int w_start_resync(struct drbd_conf *, struct drbd_work *, int);
+extern int w_req_cancel_conflict(struct drbd_work *, int);
+extern int w_read_retry_remote(struct drbd_work *, int);
+extern int w_e_end_data_req(struct drbd_work *, int);
+extern int w_e_end_rsdata_req(struct drbd_work *, int);
+extern int w_e_end_csum_rs_req(struct drbd_work *, int);
+extern int w_e_end_ov_reply(struct drbd_work *, int);
+extern int w_e_end_ov_req(struct drbd_work *, int);
+extern int w_ov_finished(struct drbd_work *, int);
+extern int w_resync_timer(struct drbd_work *, int);
+extern int w_resume_next_sg(struct drbd_work *, int);
+extern int w_send_write_hint(struct drbd_work *, int);
+extern int w_send_dblock(struct drbd_work *, int);
+extern int w_send_barrier(struct drbd_work *, int);
+extern int w_send_read_req(struct drbd_work *, int);
+extern int w_prev_work_done(struct drbd_work *, int);
+extern int w_e_reissue(struct drbd_work *, int);
+extern int w_restart_disk_io(struct drbd_work *, int);
+extern int w_send_oos(struct drbd_work *, int);
+extern int w_start_resync(struct drbd_work *, int);
 
 extern void resync_timer_fn(unsigned long data);
 extern void start_resync_timer_fn(unsigned long data);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 8f04fd0..3b49d0e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -64,10 +64,10 @@ int drbd_asender(struct drbd_thread *);
 int drbd_init(void);
 static int drbd_open(struct block_device *bdev, fmode_t mode);
 static int drbd_release(struct gendisk *gd, fmode_t mode);
-static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static int w_md_sync(struct drbd_work *w, int unused);
 static void md_sync_timer_fn(unsigned long data);
-static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);
-static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static int w_bitmap_io(struct drbd_work *w, int unused);
+static int w_go_diskless(struct drbd_work *w, int unused);
 
 MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "
 	      "Lars Ellenberg <lars@linbit.com>");
@@ -2803,9 +2803,10 @@ int drbd_bmio_clear_n_write(struct drbd_conf *mdev)
 	return rv;
 }
 
-static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int w_bitmap_io(struct drbd_work *w, int unused)
 {
 	struct bm_io_work *work = container_of(w, struct bm_io_work, w);
+	struct drbd_conf *mdev = w->mdev;
 	int rv = -EIO;
 
 	D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
@@ -2848,8 +2849,10 @@ void drbd_ldev_destroy(struct drbd_conf *mdev)
 	clear_bit(GO_DISKLESS, &mdev->flags);
 }
 
-static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int w_go_diskless(struct drbd_work *w, int unused)
 {
+	struct drbd_conf *mdev = w->mdev;
+
 	D_ASSERT(mdev->state.disk == D_FAILED);
 	/* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
 	 * inc/dec it frequently. Once we are D_DISKLESS, no one will touch
@@ -2962,8 +2965,10 @@ static void md_sync_timer_fn(unsigned long data)
 	drbd_queue_work_front(&mdev->tconn->data.work, &mdev->md_sync_work);
 }
 
-static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int w_md_sync(struct drbd_work *w, int unused)
 {
+	struct drbd_conf *mdev = w->mdev;
+
 	dev_warn(DEV, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
 #ifdef DEBUG
 	dev_warn(DEV, "last md_mark_dirty: %s:%u\n",
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 54eb53f..55fc243 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -65,7 +65,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn);
 static int drbd_disconnected(int vnr, void *p, void *data);
 
 static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
-static int e_end_block(struct drbd_conf *, struct drbd_work *, int);
+static int e_end_block(struct drbd_work *, int);
 
 
 #define GFP_TRY	(__GFP_HIGHMEM | __GFP_NOWARN)
@@ -420,7 +420,7 @@ static int drbd_process_done_ee(struct drbd_conf *mdev)
 	 */
 	list_for_each_entry_safe(peer_req, t, &work_list, w.list) {
 		/* list_del not necessary, next/prev members not touched */
-		ok = peer_req->w.cb(mdev, &peer_req->w, !ok) && ok;
+		ok = peer_req->w.cb(&peer_req->w, !ok) && ok;
 		drbd_free_ee(mdev, peer_req);
 	}
 	wake_up(&mdev->ee_wait);
@@ -1450,9 +1450,10 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
 
 /* e_end_resync_block() is called via
  * drbd_process_done_ee() by asender only */
-static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int e_end_resync_block(struct drbd_work *w, int unused)
 {
 	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
+	struct drbd_conf *mdev = w->mdev;
 	sector_t sector = peer_req->i.sector;
 	int ok;
 
@@ -1587,9 +1588,10 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
 /* e_end_block() is called via drbd_process_done_ee().
  * this means this function only runs in the asender thread
  */
-static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+static int e_end_block(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
+	struct drbd_conf *mdev = w->mdev;
 	sector_t sector = peer_req->i.sector;
 	int ok = 1, pcmd;
 
@@ -1624,9 +1626,10 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int e_send_discard_ack(struct drbd_work *w, int unused)
 {
 	struct drbd_peer_request *peer_req = (struct drbd_peer_request *)w;
+	struct drbd_conf *mdev = w->mdev;
 	int ok = 1;
 
 	D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 3667984..30a3a1d 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -40,7 +40,7 @@ struct after_state_chg_work {
 
 extern void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
 int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state);
-static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static int w_after_state_ch(struct drbd_work *w, int unused);
 static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags);
 static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
@@ -853,10 +853,11 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	return rv;
 }
 
-static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+static int w_after_state_ch(struct drbd_work *w, int unused)
 {
 	struct after_state_chg_work *ascw =
 		container_of(w, struct after_state_chg_work, w);
+	struct drbd_conf *mdev = w->mdev;
 
 	after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags);
 	if (ascw->flags & CS_WAIT_COMPLETE) {
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 3f0f84a..418f44a 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -38,9 +38,8 @@
 #include "drbd_int.h"
 #include "drbd_req.h"
 
-static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel);
-static int w_make_resync_request(struct drbd_conf *mdev,
-				 struct drbd_work *w, int cancel);
+static int w_make_ov_request(struct drbd_work *w, int cancel);
+static int w_make_resync_request(struct drbd_work *w, int cancel);
 
 
 
@@ -228,9 +227,10 @@ void drbd_endio_pri(struct bio *bio, int error)
 		complete_master_bio(mdev, &m);
 }
 
-int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_read_retry_remote(struct drbd_work *w, int cancel)
 {
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	struct drbd_conf *mdev = w->mdev;
 
 	/* We should not detach for read io-error,
 	 * but try to WRITE the P_DATA_REPLY to the failed location,
@@ -244,7 +244,7 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	}
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
-	return w_send_read_req(mdev, w, 0);
+	return w_send_read_req(w, 0);
 }
 
 void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm,
@@ -295,11 +295,10 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
 	crypto_hash_final(&desc, digest);
 }
 
-/* TODO merge common code with w_e_end_ov_req */
-int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+static int w_e_send_csum(struct drbd_work *w, int cancel)
 {
-	struct drbd_peer_request *peer_req =
-		container_of(w, struct drbd_peer_request, w);
+	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -383,14 +382,15 @@ defer:
 	return -EAGAIN;
 }
 
-int w_resync_timer(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_resync_timer(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	switch (mdev->state.conn) {
 	case C_VERIFY_S:
-		w_make_ov_request(mdev, w, cancel);
+		w_make_ov_request(w, cancel);
 		break;
 	case C_SYNC_TARGET:
-		w_make_resync_request(mdev, w, cancel);
+		w_make_resync_request(w, cancel);
 		break;
 	}
 
@@ -504,9 +504,9 @@ static int drbd_rs_number_requests(struct drbd_conf *mdev)
 	return number;
 }
 
-static int w_make_resync_request(struct drbd_conf *mdev,
-				 struct drbd_work *w, int cancel)
+static int w_make_resync_request(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	unsigned long bit;
 	sector_t sector;
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
@@ -664,8 +664,9 @@ next_sector:
 	return 1;
 }
 
-static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+static int w_make_ov_request(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	int number, i, size;
 	sector_t sector;
 	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
@@ -707,8 +708,9 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca
 	return 1;
 }
 
-int w_ov_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_ov_finished(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	kfree(w);
 	ov_oos_print(mdev);
 	drbd_resync_finished(mdev);
@@ -716,8 +718,9 @@ int w_ov_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return 1;
 }
 
-static int w_resync_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+static int w_resync_finished(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	kfree(w);
 
 	drbd_resync_finished(mdev);
@@ -901,9 +904,10 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_peer_requ
  * @w:		work object.
  * @cancel:	The connection will be closed anyways
  */
-int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_e_end_data_req(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -937,9 +941,10 @@ int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
  * @w:		work object.
  * @cancel:	The connection will be closed anyways
  */
-int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -985,9 +990,10 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	struct digest_info *di;
 	int digest_size;
 	void *digest = NULL;
@@ -1047,10 +1053,10 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-/* TODO merge common code with w_e_send_csum */
-int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_e_end_ov_req(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	sector_t sector = peer_req->i.sector;
 	unsigned int size = peer_req->i.size;
 	int digest_size;
@@ -1105,9 +1111,10 @@ void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size)
 	drbd_set_out_of_sync(mdev, sector, size);
 }
 
-int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_e_end_ov_reply(struct drbd_work *w, int cancel)
 {
 	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	struct digest_info *di;
 	void *digest;
 	sector_t sector = peer_req->i.sector;
@@ -1172,16 +1179,18 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-int w_prev_work_done(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_prev_work_done(struct drbd_work *w, int cancel)
 {
 	struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w);
+
 	complete(&b->done);
 	return 1;
 }
 
-int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_send_barrier(struct drbd_work *w, int cancel)
 {
 	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.barrier;
 	int ok = 1;
 
@@ -1210,16 +1219,18 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-int w_send_write_hint(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_send_write_hint(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
 	if (cancel)
 		return 1;
 	return drbd_send_short_cmd(mdev, P_UNPLUG_REMOTE);
 }
 
-int w_send_oos(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_send_oos(struct drbd_work *w, int cancel)
 {
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -1239,9 +1250,10 @@ int w_send_oos(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
  * @w:		work object.
  * @cancel:	The connection will be closed anyways
  */
-int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_send_dblock(struct drbd_work *w, int cancel)
 {
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -1261,9 +1273,10 @@ int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
  * @w:		work object.
  * @cancel:	The connection will be closed anyways
  */
-int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_send_read_req(struct drbd_work *w, int cancel)
 {
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	struct drbd_conf *mdev = w->mdev;
 	int ok;
 
 	if (unlikely(cancel)) {
@@ -1285,9 +1298,10 @@ int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 	return ok;
 }
 
-int w_restart_disk_io(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_restart_disk_io(struct drbd_work *w, int cancel)
 {
 	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	struct drbd_conf *mdev = w->mdev;
 
 	if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
 		drbd_al_begin_io(mdev, req->i.sector);
@@ -1447,8 +1461,10 @@ void start_resync_timer_fn(unsigned long data)
 	drbd_queue_work(&mdev->tconn->data.work, &mdev->start_resync_work);
 }
 
-int w_start_resync(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+int w_start_resync(struct drbd_work *w, int cancel)
 {
+	struct drbd_conf *mdev = w->mdev;
+
 	if (atomic_read(&mdev->unacked_cnt) || atomic_read(&mdev->rs_pending_cnt)) {
 		dev_warn(DEV, "w_start_resync later...\n");
 		mdev->start_resync_timer.expires = jiffies + HZ/10;
@@ -1702,7 +1718,7 @@ int drbd_worker(struct drbd_thread *thi)
 		list_del_init(&w->list);
 		spin_unlock_irq(&tconn->data.work.q_lock);
 
-		if (!w->cb(w->mdev, w, tconn->volume0->state.conn < C_CONNECTED)) {
+		if (!w->cb(w, tconn->volume0->state.conn < C_CONNECTED)) {
 			/* dev_warn(DEV, "worker: a callback failed! \n"); */
 			if (tconn->volume0->state.conn >= C_CONNECTED)
 				drbd_force_state(tconn->volume0,
@@ -1718,7 +1734,7 @@ int drbd_worker(struct drbd_thread *thi)
 		while (!list_empty(&work_list)) {
 			w = list_entry(work_list.next, struct drbd_work, list);
 			list_del_init(&w->list);
-			w->cb(w->mdev, w, 1);
+			w->cb(w, 1);
 		}
 
 		spin_lock_irq(&tconn->data.work.q_lock);
-- 
1.7.4.1


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

* [PATCH 103/118] drbd: Converted drbd_send_ping() and related functions from mdev to tconn
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (101 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 102/118] drbd: Generalized the work callbacks Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 104/118] drbd: Extracted after_conn_state_ch() out of after_state_ch() Philipp Reisner
                   ` (16 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |   21 ++++++++++++++-------
 drivers/block/drbd/drbd_main.c     |   17 +++++++++--------
 drivers/block/drbd/drbd_receiver.c |   11 ++++++-----
 drivers/block/drbd/drbd_state.c    |    1 +
 drivers/block/drbd/drbd_worker.c   |   10 ++++++----
 5 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 12f0c5e..9c63b10 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -789,7 +789,6 @@ enum {
 	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
 				 * the peer, if it changed there as well. */
 	CONN_DRY_RUN,		/* Expect disconnect after resync handshake. */
-	GOT_PING_ACK,		/* set when we receive a ping_ack packet, misc wait gets woken */
 	NEW_CUR_UUID,		/* Create new current UUID when thawing IO */
 	AL_SUSPENDED,		/* Activity logging is currently suspended. */
 	AHEAD_TO_SYNC_SOURCE,   /* Ahead -> SyncSource queued */
@@ -912,6 +911,7 @@ enum {
 	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
 	SEND_PING,		/* whether asender should send a ping asap */
 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
+	GOT_PING_ACK,		/* set when we receive a ping_ack packet, ping_wait gets woken */
 };
 
 struct drbd_tconn {			/* is a resource from the config file */
@@ -924,6 +924,7 @@ struct drbd_tconn {			/* is a resource from the config file */
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
 	atomic_t net_cnt;		/* Users of net_conf */
 	wait_queue_head_t net_cnt_wait;
+	wait_queue_head_t ping_wait;		/* Woken upon reception of a ping, and a state change */
 
 	struct drbd_socket data;	/* data/barrier/cstate/parameter packets */
 	struct drbd_socket meta;	/* ping/ack (metadata) packets */
@@ -1179,12 +1180,12 @@ extern int drbd_send_state(struct drbd_conf *mdev);
 extern int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct 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, int use_data_socket,
+			 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);
 #define USE_DATA_SOCKET 1
 #define USE_META_SOCKET 0
-extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
-			 enum drbd_packet cmd, struct p_header *h, size_t size);
 extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc);
 extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
 			u32 set_size);
@@ -1885,6 +1886,12 @@ static inline int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
 	return _conn_send_cmd(mdev->tconn, mdev->vnr, sock, cmd, h, size, msg_flags);
 }
 
+static inline int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
+				enum drbd_packet cmd, struct p_header *h, size_t size)
+{
+	return conn_send_cmd(mdev->tconn, mdev->vnr, use_data_socket, cmd, h, size);
+}
+
 static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
 				      enum drbd_packet cmd)
 {
@@ -1892,16 +1899,16 @@ static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
 	return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h));
 }
 
-static inline int drbd_send_ping(struct drbd_conf *mdev)
+static inline int drbd_send_ping(struct drbd_tconn *tconn)
 {
 	struct p_header h;
-	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING, &h, sizeof(h));
+	return conn_send_cmd(tconn, 0, USE_META_SOCKET, P_PING, &h, sizeof(h));
 }
 
-static inline int drbd_send_ping_ack(struct drbd_conf *mdev)
+static inline int drbd_send_ping_ack(struct drbd_tconn *tconn)
 {
 	struct p_header h;
-	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h));
+	return conn_send_cmd(tconn, 0, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h));
 }
 
 static inline void drbd_thread_stop(struct drbd_thread *thi)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 3b49d0e..9d6eb74 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -719,29 +719,29 @@ int _conn_send_cmd(struct drbd_tconn *tconn, int vnr, struct socket *sock,
 /* don't pass the socket. we may only look at it
  * when we hold the appropriate socket mutex.
  */
-int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
+int conn_send_cmd(struct drbd_tconn *tconn, int vnr, int use_data_socket,
 		  enum drbd_packet cmd, struct p_header *h, size_t size)
 {
 	int ok = 0;
 	struct socket *sock;
 
 	if (use_data_socket) {
-		mutex_lock(&mdev->tconn->data.mutex);
-		sock = mdev->tconn->data.socket;
+		mutex_lock(&tconn->data.mutex);
+		sock = tconn->data.socket;
 	} else {
-		mutex_lock(&mdev->tconn->meta.mutex);
-		sock = mdev->tconn->meta.socket;
+		mutex_lock(&tconn->meta.mutex);
+		sock = tconn->meta.socket;
 	}
 
 	/* drbd_disconnect() could have called drbd_free_sock()
 	 * while we were waiting in down()... */
 	if (likely(sock != NULL))
-		ok = _drbd_send_cmd(mdev, sock, cmd, h, size, 0);
+		ok = _conn_send_cmd(tconn, vnr, sock, cmd, h, size, 0);
 
 	if (use_data_socket)
-		mutex_unlock(&mdev->tconn->data.mutex);
+		mutex_unlock(&tconn->data.mutex);
 	else
-		mutex_unlock(&mdev->tconn->meta.mutex);
+		mutex_unlock(&tconn->meta.mutex);
 	return ok;
 }
 
@@ -2203,6 +2203,7 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 	spin_lock_init(&tconn->req_lock);
 	atomic_set(&tconn->net_cnt, 0);
 	init_waitqueue_head(&tconn->net_cnt_wait);
+	init_waitqueue_head(&tconn->ping_wait);
 	idr_init(&tconn->volumes);
 
 	drbd_init_workqueue(&tconn->data.work);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 55fc243..113d37f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4282,16 +4282,17 @@ static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packet cmd)
 
 static int got_Ping(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
-	return drbd_send_ping_ack(mdev);
+	return drbd_send_ping_ack(mdev->tconn);
 
 }
 
 static int got_PingAck(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
+	struct drbd_tconn *tconn = mdev->tconn;
 	/* restore idle timeout */
-	mdev->tconn->meta.socket->sk->sk_rcvtimeo = mdev->tconn->net_conf->ping_int*HZ;
-	if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
-		wake_up(&mdev->misc_wait);
+	tconn->meta.socket->sk->sk_rcvtimeo = tconn->net_conf->ping_int*HZ;
+	if (!test_and_set_bit(GOT_PING_ACK, &tconn->flags))
+		wake_up(&tconn->ping_wait);
 
 	return true;
 }
@@ -4613,7 +4614,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->volume0)) {
+			if (!drbd_send_ping(tconn)) {
 				conn_err(tconn, "drbd_send_ping has failed\n");
 				goto reconnect;
 			}
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 30a3a1d..d577715 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -737,6 +737,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 
 	wake_up(&mdev->misc_wait);
 	wake_up(&mdev->state_wait);
+	wake_up(&mdev->tconn->ping_wait);
 
 	/* aborted verify run. log the last position */
 	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 418f44a..8539df2 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -730,10 +730,12 @@ static int w_resync_finished(struct drbd_work *w, int cancel)
 
 static void ping_peer(struct drbd_conf *mdev)
 {
-	clear_bit(GOT_PING_ACK, &mdev->flags);
-	request_ping(mdev->tconn);
-	wait_event(mdev->misc_wait,
-		   test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
+	struct drbd_tconn *tconn = mdev->tconn;
+
+	clear_bit(GOT_PING_ACK, &tconn->flags);
+	request_ping(tconn);
+	wait_event(tconn->ping_wait,
+		   test_bit(GOT_PING_ACK, &tconn->flags) || mdev->state.conn < C_CONNECTED);
 }
 
 int drbd_resync_finished(struct drbd_conf *mdev)
-- 
1.7.4.1


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

* [PATCH 104/118] drbd: Extracted after_conn_state_ch() out of after_state_ch()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (102 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 103/118] drbd: Converted drbd_send_ping() and related functions from mdev to tconn Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 105/118] drbd: Renamed is_valid_state_transition() to is_valid_soft_transition() Philipp Reisner
                   ` (15 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   26 ++++++++++++++++----------
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index d577715..18feba6 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -45,10 +45,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags);
 static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
 				union drbd_state ns, enum chg_state_flags flags);
-static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
-static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort);
 
 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
@@ -98,6 +94,15 @@ void drbd_force_state(struct drbd_conf *mdev,
 	drbd_change_state(mdev, CS_HARD, mask, val);
 }
 
+static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
+static enum drbd_state_rv is_valid_state_transition(struct drbd_conf *,
+						    union drbd_state,
+						    union drbd_state);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, const char **warn_sync_abort);
+int drbd_send_state_req(struct drbd_conf *,
+			union drbd_state, union drbd_state);
+
 static enum drbd_state_rv
 _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	     union drbd_state val)
@@ -123,7 +128,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	if (!rv) {
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS) {
-			rv = is_valid_soft_transition(os, ns);
+			rv = is_valid_state_transition(mdev, ns, os);
 			if (rv == SS_SUCCESS)
 				rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
 		}
@@ -166,7 +171,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	if (cl_wide_st_chg(mdev, os, ns)) {
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS)
-			rv = is_valid_soft_transition(os, ns);
+			rv = is_valid_state_transition(mdev, ns, os);
 		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 		if (rv < SS_SUCCESS) {
@@ -339,13 +344,14 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 }
 
 /**
- * is_valid_soft_transition() - Returns an SS_ error code if the state transition is not possible
+ * is_valid_state_transition() - Returns an SS_ error code if the state transition is not possible
  * @mdev:	DRBD device.
  * @ns:		new state.
  * @os:		old state.
  */
 static enum drbd_state_rv
-is_valid_soft_transition(union drbd_state os, union drbd_state ns)
+is_valid_state_transition(struct drbd_conf *mdev, union drbd_state ns,
+			  union drbd_state os)
 {
 	enum drbd_state_rv rv = SS_SUCCESS;
 
@@ -651,9 +657,9 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 			   this happen...*/
 
 			if (is_valid_state(mdev, os) == rv)
-				rv = is_valid_soft_transition(os, ns);
+				rv = is_valid_state_transition(mdev, ns, os);
 		} else
-			rv = is_valid_soft_transition(os, ns);
+			rv = is_valid_state_transition(mdev, ns, os);
 	}
 
 	if (rv < SS_SUCCESS) {
-- 
1.7.4.1


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

* [PATCH 105/118] drbd: Renamed is_valid_state_transition() to is_valid_soft_transition()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (103 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 104/118] drbd: Extracted after_conn_state_ch() out of after_state_ch() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 106/118] drbd: Extracted is_valid_transition() out of sanitize_state() Philipp Reisner
                   ` (14 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

And removed the unused mdev parameter, and made the order of
the state parameters: os, ns

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   26 ++++++++++----------------
 1 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 18feba6..d577715 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -45,6 +45,10 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags);
 static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
 				union drbd_state ns, enum chg_state_flags flags);
+static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
+static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, const char **warn_sync_abort);
 
 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
@@ -94,15 +98,6 @@ void drbd_force_state(struct drbd_conf *mdev,
 	drbd_change_state(mdev, CS_HARD, mask, val);
 }
 
-static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
-static enum drbd_state_rv is_valid_state_transition(struct drbd_conf *,
-						    union drbd_state,
-						    union drbd_state);
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort);
-int drbd_send_state_req(struct drbd_conf *,
-			union drbd_state, union drbd_state);
-
 static enum drbd_state_rv
 _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	     union drbd_state val)
@@ -128,7 +123,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	if (!rv) {
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS) {
-			rv = is_valid_state_transition(mdev, ns, os);
+			rv = is_valid_soft_transition(os, ns);
 			if (rv == SS_SUCCESS)
 				rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
 		}
@@ -171,7 +166,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	if (cl_wide_st_chg(mdev, os, ns)) {
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS)
-			rv = is_valid_state_transition(mdev, ns, os);
+			rv = is_valid_soft_transition(os, ns);
 		spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
 
 		if (rv < SS_SUCCESS) {
@@ -344,14 +339,13 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 }
 
 /**
- * is_valid_state_transition() - Returns an SS_ error code if the state transition is not possible
+ * is_valid_soft_transition() - Returns an SS_ error code if the state transition is not possible
  * @mdev:	DRBD device.
  * @ns:		new state.
  * @os:		old state.
  */
 static enum drbd_state_rv
-is_valid_state_transition(struct drbd_conf *mdev, union drbd_state ns,
-			  union drbd_state os)
+is_valid_soft_transition(union drbd_state os, union drbd_state ns)
 {
 	enum drbd_state_rv rv = SS_SUCCESS;
 
@@ -657,9 +651,9 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 			   this happen...*/
 
 			if (is_valid_state(mdev, os) == rv)
-				rv = is_valid_state_transition(mdev, ns, os);
+				rv = is_valid_soft_transition(os, ns);
 		} else
-			rv = is_valid_state_transition(mdev, ns, os);
+			rv = is_valid_soft_transition(os, ns);
 	}
 
 	if (rv < SS_SUCCESS) {
-- 
1.7.4.1


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

* [PATCH 106/118] drbd: Extracted is_valid_transition() out of sanitize_state()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (104 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 105/118] drbd: Renamed is_valid_state_transition() to is_valid_soft_transition() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 107/118] drbd: Extracted is_valid_conn_transition() out of is_valid_transition() Philipp Reisner
                   ` (13 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   71 +++++++++++++++++++++++++++------------
 1 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index d577715..3199bf9 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -47,6 +47,7 @@ static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
 				union drbd_state ns, enum chg_state_flags flags);
 static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
 static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
+static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
 static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
 				       union drbd_state ns, const char **warn_sync_abort);
 
@@ -112,15 +113,17 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags))
 		return SS_CW_FAILED_BY_PEER;
 
-	rv = 0;
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
 	ns = sanitize_state(mdev, os, ns, NULL);
+	rv = is_valid_transition(os, ns);
+	if (rv == SS_SUCCESS)
+		rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
 
 	if (!cl_wide_st_chg(mdev, os, ns))
 		rv = SS_CW_NO_NEED;
-	if (!rv) {
+	if (rv == SS_UNKNOWN_ERROR) {
 		rv = is_valid_state(mdev, ns);
 		if (rv == SS_SUCCESS) {
 			rv = is_valid_soft_transition(os, ns);
@@ -160,8 +163,10 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
-
 	ns = sanitize_state(mdev, os, ns, NULL);
+	rv = is_valid_transition(os, ns);
+	if (rv < SS_SUCCESS)
+		goto abort;
 
 	if (cl_wide_st_chg(mdev, os, ns)) {
 		rv = is_valid_state(mdev, ns);
@@ -340,6 +345,8 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
 
 /**
  * is_valid_soft_transition() - Returns an SS_ error code if the state transition is not possible
+ * This function limits state transitions that may be declined by DRBD. I.e.
+ * user requests (aka soft transitions).
  * @mdev:	DRBD device.
  * @ns:		new state.
  * @os:		old state.
@@ -390,6 +397,40 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns)
 }
 
 /**
+ * is_valid_transition() - Returns an SS_ error code if the state transition is not possible
+ * This limits hard state transitions. Hard state transitions are facts there are
+ * imposed on DRBD by the environment. E.g. disk broke or network broke down.
+ * But those hard state transitions are still not allowed to do everything.
+ * @ns:		new state.
+ * @os:		old state.
+ */
+static enum drbd_state_rv
+is_valid_transition(union drbd_state os, union drbd_state ns)
+{
+	enum drbd_state_rv rv = SS_SUCCESS;
+
+	/* Disallow Network errors to configure a device's network part */
+	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
+	    os.conn <= C_DISCONNECTING)
+		rv = SS_NEED_CONNECTION;
+
+	/* After a network error only C_UNCONNECTED or C_DISCONNECTING may follow. */
+	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
+	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	/* After C_DISCONNECTING only C_STANDALONE may follow */
+	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	/* we cannot fail (again) if we already detached */
+	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
+		rv = SS_IS_DISKLESS;
+
+	return rv;
+}
+
+/**
  * sanitize_state() - Resolves implicitly necessary additional changes to a state transition
  * @mdev:	DRBD device.
  * @os:		old state.
@@ -411,30 +452,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
 		put_ldev(mdev);
 	}
 
-	/* Disallow Network errors to configure a device's network part */
-	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
-	    os.conn <= C_DISCONNECTING)
-		ns.conn = os.conn;
-
-	/* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow.
-	 * If you try to go into some Sync* state, that shall fail (elsewhere). */
-	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
-	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN)
-		ns.conn = os.conn;
-
-	/* we cannot fail (again) if we already detached */
-	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
-		ns.disk = D_DISKLESS;
-
 	/* if we are only D_ATTACHING yet,
 	 * we can (and should) go directly to D_DISKLESS. */
 	if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
 		ns.disk = D_DISKLESS;
 
-	/* After C_DISCONNECTING only C_STANDALONE may follow */
-	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
-		ns.conn = os.conn;
-
+	/* Implications from connection to peer and peer_isp */
 	if (ns.conn < C_CONNECTED) {
 		ns.peer_isp = 0;
 		ns.peer = R_UNKNOWN;
@@ -641,6 +664,10 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	if (ns.i == os.i)
 		return SS_NOTHING_TO_DO;
 
+	rv = is_valid_transition(os, ns);
+	if (rv < SS_SUCCESS)
+		return rv;
+
 	if (!(flags & CS_HARD)) {
 		/*  pre-state-change checks ; only look at ns  */
 		/* See drbd_state_sw_errors in drbd_strings.c */
-- 
1.7.4.1


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

* [PATCH 107/118] drbd: Extracted is_valid_conn_transition() out of is_valid_transition()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (105 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 106/118] drbd: Extracted is_valid_transition() out of sanitize_state() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 108/118] drbd: Removed the os parameter form sanitize_state() Philipp Reisner
                   ` (12 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   37 +++++++++++++++++++++++--------------
 1 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 3199bf9..b381faa 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -396,33 +396,42 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns)
 	return rv;
 }
 
-/**
- * is_valid_transition() - Returns an SS_ error code if the state transition is not possible
- * This limits hard state transitions. Hard state transitions are facts there are
- * imposed on DRBD by the environment. E.g. disk broke or network broke down.
- * But those hard state transitions are still not allowed to do everything.
- * @ns:		new state.
- * @os:		old state.
- */
 static enum drbd_state_rv
-is_valid_transition(union drbd_state os, union drbd_state ns)
+is_valid_conn_transition(enum drbd_conns oc, enum drbd_conns nc)
 {
 	enum drbd_state_rv rv = SS_SUCCESS;
 
 	/* Disallow Network errors to configure a device's network part */
-	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
-	    os.conn <= C_DISCONNECTING)
+	if ((nc >= C_TIMEOUT && nc <= C_TEAR_DOWN) && oc <= C_DISCONNECTING)
 		rv = SS_NEED_CONNECTION;
 
 	/* After a network error only C_UNCONNECTED or C_DISCONNECTING may follow. */
-	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
-	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING)
+	if (oc >= C_TIMEOUT && oc <= C_TEAR_DOWN && nc != C_UNCONNECTED && nc != C_DISCONNECTING)
 		rv = SS_IN_TRANSIENT_STATE;
 
 	/* After C_DISCONNECTING only C_STANDALONE may follow */
-	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
+	if (oc == C_DISCONNECTING && nc != C_STANDALONE)
 		rv = SS_IN_TRANSIENT_STATE;
 
+	return rv;
+}
+
+
+/**
+ * is_valid_transition() - Returns an SS_ error code if the state transition is not possible
+ * This limits hard state transitions. Hard state transitions are facts there are
+ * imposed on DRBD by the environment. E.g. disk broke or network broke down.
+ * But those hard state transitions are still not allowed to do everything.
+ * @ns:		new state.
+ * @os:		old state.
+ */
+static enum drbd_state_rv
+is_valid_transition(union drbd_state os, union drbd_state ns)
+{
+	enum drbd_state_rv rv;
+
+	rv = is_valid_conn_transition(os.conn, ns.conn);
+
 	/* we cannot fail (again) if we already detached */
 	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
 		rv = SS_IS_DISKLESS;
-- 
1.7.4.1


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

* [PATCH 108/118] drbd: Removed the os parameter form sanitize_state()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (106 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 107/118] drbd: Extracted is_valid_conn_transition() out of is_valid_transition() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 109/118] drbd: Code de-duplication; new function apply_mask_val() Philipp Reisner
                   ` (11 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   39 +++++++++++++++++++--------------------
 1 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index b381faa..02516ed 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -48,8 +48,8 @@ static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
 static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
 static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
 static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns,
+				       const char **warn_sync_abort);
 
 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
@@ -116,7 +116,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
+	ns = sanitize_state(mdev, ns, NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv == SS_SUCCESS)
 		rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
@@ -163,7 +163,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
+	ns = sanitize_state(mdev, ns, NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv < SS_SUCCESS)
 		goto abort;
@@ -436,6 +436,13 @@ is_valid_transition(union drbd_state os, union drbd_state ns)
 	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
 		rv = SS_IS_DISKLESS;
 
+	/* if we are only D_ATTACHING yet,
+	 * we can (and should) go directly to D_DISKLESS. */
+	if (ns.disk == D_FAILED && os.disk == D_ATTACHING) {
+		printk("TODO: FIX ME\n");
+		rv = SS_IS_DISKLESS;
+	}
+
 	return rv;
 }
 
@@ -449,8 +456,8 @@ is_valid_transition(union drbd_state os, union drbd_state ns)
  * When we loose connection, we have to set the state of the peers disk (pdsk)
  * to D_UNKNOWN. This rule and many more along those lines are in this function.
  */
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort)
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns,
+				       const char **warn_sync_abort)
 {
 	enum drbd_fencing_p fp;
 	enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max;
@@ -461,11 +468,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
 		put_ldev(mdev);
 	}
 
-	/* if we are only D_ATTACHING yet,
-	 * we can (and should) go directly to D_DISKLESS. */
-	if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
-		ns.disk = D_DISKLESS;
-
 	/* Implications from connection to peer and peer_isp */
 	if (ns.conn < C_CONNECTED) {
 		ns.peer_isp = 0;
@@ -478,12 +480,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
 	if (ns.conn == C_STANDALONE && ns.disk == D_DISKLESS && ns.role == R_SECONDARY)
 		ns.aftr_isp = 0;
 
+	/* An implication of the disk states onto the connection state */
 	/* Abort resync if a disk fails/detaches */
-	if (os.conn > C_CONNECTED && ns.conn > C_CONNECTED &&
-	    (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
+	if (ns.conn > C_CONNECTED && (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
 		if (warn_sync_abort)
 			*warn_sync_abort =
-				os.conn == C_VERIFY_S || os.conn == C_VERIFY_T ?
+				ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T ?
 				"Online-verify" : "Resync";
 		ns.conn = C_CONNECTED;
 	}
@@ -591,13 +593,11 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
 	}
 
 	if (fp == FP_STONITH &&
-	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
-	    !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
+	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED))
 		ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
 
 	if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
-	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
-	    !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
+	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
 		ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
 
 	if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
@@ -668,8 +668,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 
 	os = mdev->state;
 
-	ns = sanitize_state(mdev, os, ns, &warn_sync_abort);
-
+	ns = sanitize_state(mdev, ns, &warn_sync_abort);
 	if (ns.i == os.i)
 		return SS_NOTHING_TO_DO;
 
-- 
1.7.4.1


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

* [PATCH 109/118] drbd: Code de-duplication; new function apply_mask_val()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (107 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 108/118] drbd: Removed the os parameter form sanitize_state() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 110/118] drbd: Killed volume0; last step of multi-volume-enablement Philipp Reisner
                   ` (10 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_state.c |   22 +++++++++++++---------
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 02516ed..0100aab 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -69,17 +69,24 @@ static int cl_wide_st_chg(struct drbd_conf *mdev,
 		(os.conn == C_CONNECTED && ns.conn == C_VERIFY_S);
 }
 
+static union drbd_state
+apply_mask_val(union drbd_state os, union drbd_state mask, union drbd_state val)
+{
+	union drbd_state ns;
+	ns.i = (os.i & ~mask.i) | val.i;
+	return ns;
+}
+
 enum drbd_state_rv
 drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
 		  union drbd_state mask, union drbd_state val)
 {
 	unsigned long flags;
-	union drbd_state os, ns;
+	union drbd_state ns;
 	enum drbd_state_rv rv;
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
+	ns = apply_mask_val(mdev->state, mask, val);
 	rv = _drbd_set_state(mdev, ns, f, NULL);
 	ns = mdev->state;
 	spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
@@ -115,8 +122,7 @@ _req_st_cond(struct drbd_conf *mdev, union drbd_state mask,
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, ns, NULL);
+	ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv == SS_SUCCESS)
 		rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
@@ -162,8 +168,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, ns, NULL);
+	ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv < SS_SUCCESS)
 		goto abort;
@@ -199,8 +204,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 			goto abort;
 		}
 		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
-		os = mdev->state;
-		ns.i = (os.i & ~mask.i) | val.i;
+		ns = apply_mask_val(mdev->state, mask, val);
 		rv = _drbd_set_state(mdev, ns, f, &done);
 		drbd_state_unlock(mdev);
 	} else {
-- 
1.7.4.1


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

* [PATCH 110/118] drbd: Killed volume0; last step of multi-volume-enablement
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (108 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 109/118] drbd: Code de-duplication; new function apply_mask_val() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 111/118] drbd: Removed drbd_state_lock() and drbd_state_unlock() Philipp Reisner
                   ` (9 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_int.h      |    4 +-
 drivers/block/drbd/drbd_main.c     |    8 +-
 drivers/block/drbd/drbd_nl.c       |    2 +-
 drivers/block/drbd/drbd_receiver.c |   39 +++---
 drivers/block/drbd/drbd_state.c    |  292 +++++++++++++++++++++++++++++-------
 drivers/block/drbd/drbd_state.h    |   10 ++
 drivers/block/drbd/drbd_worker.c   |    7 +-
 7 files changed, 276 insertions(+), 86 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9c63b10..0ea0b15 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -917,8 +917,8 @@ enum {
 struct drbd_tconn {			/* is a resource from the config file */
 	char *name;			/* Resource name */
 	struct list_head all_tconn;	/* List of all drbd_tconn, prot by global_state_lock */
-	struct drbd_conf *volume0;	/* TODO: Remove me again */
 	struct idr volumes;             /* <tconn, vnr> to mdev mapping */
+	enum drbd_conns cstate;        /* Only C_STANDALONE to C_WF_REPORT_PARAMS */
 
 	unsigned long flags;
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
@@ -2023,7 +2023,7 @@ static inline int get_net_conf(struct drbd_tconn *tconn)
 	int have_net_conf;
 
 	atomic_inc(&tconn->net_cnt);
-	have_net_conf = tconn->volume0->state.conn >= C_UNCONNECTED;
+	have_net_conf = tconn->cstate >= C_UNCONNECTED;
 	if (!have_net_conf)
 		put_net_conf(tconn);
 	return have_net_conf;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9d6eb74..2c1df75 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1356,7 +1356,7 @@ static int we_should_drop_the_connection(struct drbd_tconn *tconn, struct socket
 	drop_it =   tconn->meta.socket == sock
 		|| !tconn->asender.task
 		|| get_t_state(&tconn->asender) != RUNNING
-		|| tconn->volume0->state.conn < C_CONNECTED;
+		|| tconn->cstate < C_WF_REPORT_PARAMS;
 
 	if (drop_it)
 		return true;
@@ -1717,9 +1717,9 @@ int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
 			conn_err(tconn, "%s_sendmsg returned %d\n",
 				 sock == tconn->meta.socket ? "msock" : "sock",
 				 rv);
-			drbd_force_state(tconn->volume0, NS(conn, C_BROKEN_PIPE));
+			conn_request_state(tconn, NS(conn, C_BROKEN_PIPE), CS_HARD);
 		} else
-			drbd_force_state(tconn->volume0, NS(conn, C_TIMEOUT));
+			conn_request_state(tconn, NS(conn, C_TIMEOUT), CS_HARD);
 	}
 
 	return sent;
@@ -2200,6 +2200,7 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 	if (!tconn->name)
 		goto fail;
 
+	tconn->cstate = C_STANDALONE;
 	spin_lock_init(&tconn->req_lock);
 	atomic_set(&tconn->net_cnt, 0);
 	init_waitqueue_head(&tconn->net_cnt_wait);
@@ -2270,7 +2271,6 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 	if (!zalloc_cpumask_var(&mdev->tconn->cpu_mask, GFP_KERNEL))
 		goto out_no_cpumask;
 
-	mdev->tconn->volume0 = mdev;
 	mdev->minor = minor;
 
 	drbd_init_set_defaults(mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 0debe58..eeb284a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1547,7 +1547,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 	mdev->tconn->int_dig_out=int_dig_out;
 	mdev->tconn->int_dig_in=int_dig_in;
 	mdev->tconn->int_dig_vv=int_dig_vv;
-	retcode = _drbd_set_state(_NS(mdev, conn, C_UNCONNECTED), CS_VERBOSE, NULL);
+	retcode = _conn_request_state(mdev->tconn, NS(conn, C_UNCONNECTED), CS_VERBOSE);
 	spin_unlock_irq(&mdev->tconn->req_lock);
 
 	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 113d37f..f755134 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -551,7 +551,7 @@ static int drbd_recv(struct drbd_tconn *tconn, void *buf, size_t size)
 	set_fs(oldfs);
 
 	if (rv != size)
-		drbd_force_state(tconn->volume0, NS(conn, C_BROKEN_PIPE));
+		conn_request_state(tconn, NS(conn, C_BROKEN_PIPE), CS_HARD);
 
 	return rv;
 }
@@ -647,7 +647,7 @@ out:
 			conn_err(tconn, "%s failed, err = %d\n", what, err);
 		}
 		if (disconnect_on_error)
-			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
+			conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
 	}
 	put_net_conf(tconn);
 	return sock;
@@ -694,7 +694,7 @@ out:
 	if (err < 0) {
 		if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) {
 			conn_err(tconn, "%s failed, err = %d\n", what, err);
-			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
+			conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
 		}
 	}
 	put_net_conf(tconn);
@@ -776,7 +776,7 @@ static int drbd_connect(struct drbd_tconn *tconn)
 	struct socket *s, *sock, *msock;
 	int try, h, ok;
 
-	if (drbd_request_state(tconn->volume0, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
+	if (conn_request_state(tconn, NS(conn, C_WF_CONNECTION), CS_VERBOSE) < SS_SUCCESS)
 		return -2;
 
 	clear_bit(DISCARD_CONCURRENT, &tconn->flags);
@@ -850,7 +850,7 @@ retry:
 			}
 		}
 
-		if (tconn->volume0->state.conn <= C_DISCONNECTING)
+		if (tconn->cstate <= C_DISCONNECTING)
 			goto out_release_sockets;
 		if (signal_pending(current)) {
 			flush_signals(current);
@@ -912,7 +912,7 @@ retry:
 		}
 	}
 
-	if (drbd_request_state(tconn->volume0, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS)
+	if (conn_request_state(tconn, NS(conn, C_WF_REPORT_PARAMS), CS_VERBOSE) < SS_SUCCESS)
 		return 0;
 
 	sock->sk->sk_sndtimeo = tconn->net_conf->timeout*HZ/10;
@@ -3820,7 +3820,7 @@ static void drbdd(struct drbd_tconn *tconn)
 
 	if (0) {
 	err_out:
-		drbd_force_state(tconn->volume0, NS(conn, C_PROTOCOL_ERROR));
+		conn_request_state(tconn, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
 	}
 }
 
@@ -3837,10 +3837,10 @@ void drbd_flush_workqueue(struct drbd_conf *mdev)
 
 static void drbd_disconnect(struct drbd_tconn *tconn)
 {
-	union drbd_state os, ns;
+	enum drbd_conns oc;
 	int rv = SS_UNKNOWN_ERROR;
 
-	if (tconn->volume0->state.conn == C_STANDALONE)
+	if (tconn->cstate == C_STANDALONE)
 		return;
 
 	/* asender does not clean up anything. it must not interfere, either */
@@ -3852,16 +3852,13 @@ static void drbd_disconnect(struct drbd_tconn *tconn)
 	conn_info(tconn, "Connection closed\n");
 
 	spin_lock_irq(&tconn->req_lock);
-	os = tconn->volume0->state;
-	if (os.conn >= C_UNCONNECTED) {
-		/* Do not restart in case we are C_DISCONNECTING */
-		ns.i = os.i;
-		ns.conn = C_UNCONNECTED;
-		rv = _drbd_set_state(tconn->volume0, ns, CS_VERBOSE, NULL);
-	}
+	oc = tconn->cstate;
+	if (oc >= C_UNCONNECTED)
+		rv = _conn_request_state(tconn, NS(conn, C_UNCONNECTED), CS_VERBOSE);
+
 	spin_unlock_irq(&tconn->req_lock);
 
-	if (os.conn == C_DISCONNECTING) {
+	if (oc == C_DISCONNECTING) {
 		wait_event(tconn->net_cnt_wait, atomic_read(&tconn->net_cnt) == 0);
 
 		crypto_free_hash(tconn->cram_hmac_tfm);
@@ -3869,7 +3866,7 @@ static void drbd_disconnect(struct drbd_tconn *tconn)
 
 		kfree(tconn->net_conf);
 		tconn->net_conf = NULL;
-		drbd_request_state(tconn->volume0, NS(conn, C_STANDALONE));
+		conn_request_state(tconn, NS(conn, C_STANDALONE), CS_VERBOSE);
 	}
 }
 
@@ -4243,7 +4240,7 @@ int drbdd_init(struct drbd_thread *thi)
 		}
 		if (h == -1) {
 			conn_warn(tconn, "Discarding network configuration.\n");
-			drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
+			conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
 		}
 	} while (h == 0);
 
@@ -4712,11 +4709,11 @@ int drbd_asender(struct drbd_thread *thi)
 
 	if (0) {
 reconnect:
-		drbd_force_state(tconn->volume0, NS(conn, C_NETWORK_FAILURE));
+		conn_request_state(tconn, NS(conn, C_NETWORK_FAILURE), CS_HARD);
 	}
 	if (0) {
 disconnect:
-		drbd_force_state(tconn->volume0, NS(conn, C_DISCONNECTING));
+		conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
 	}
 	clear_bit(SIGNAL_ASENDER, &tconn->flags);
 
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 0100aab..405ed12 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -43,8 +43,7 @@ int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state);
 static int w_after_state_ch(struct drbd_work *w, int unused);
 static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags);
-static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
-				union drbd_state ns, enum chg_state_flags flags);
+static void after_all_state_ch(struct drbd_tconn *tconn, union drbd_state ns);
 static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
 static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
 static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
@@ -275,6 +274,51 @@ void print_st_err(struct drbd_conf *mdev, union drbd_state os,
 	print_st(mdev, "wanted", ns);
 }
 
+static void print_state_change(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns,
+			       enum chg_state_flags flags)
+{
+	char *pbp, pb[300];
+	pbp = pb;
+	*pbp = 0;
+	if (ns.role != os.role)
+		pbp += sprintf(pbp, "role( %s -> %s ) ",
+			       drbd_role_str(os.role),
+			       drbd_role_str(ns.role));
+	if (ns.peer != os.peer)
+		pbp += sprintf(pbp, "peer( %s -> %s ) ",
+			       drbd_role_str(os.peer),
+			       drbd_role_str(ns.peer));
+	if (ns.conn != os.conn && !(flags & CS_NO_CSTATE_CHG))
+		pbp += sprintf(pbp, "conn( %s -> %s ) ",
+			       drbd_conn_str(os.conn),
+			       drbd_conn_str(ns.conn));
+	if (ns.disk != os.disk)
+		pbp += sprintf(pbp, "disk( %s -> %s ) ",
+			       drbd_disk_str(os.disk),
+			       drbd_disk_str(ns.disk));
+	if (ns.pdsk != os.pdsk)
+		pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
+			       drbd_disk_str(os.pdsk),
+			       drbd_disk_str(ns.pdsk));
+	if (is_susp(ns) != is_susp(os))
+		pbp += sprintf(pbp, "susp( %d -> %d ) ",
+			       is_susp(os),
+			       is_susp(ns));
+	if (ns.aftr_isp != os.aftr_isp)
+		pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ",
+			       os.aftr_isp,
+			       ns.aftr_isp);
+	if (ns.peer_isp != os.peer_isp)
+		pbp += sprintf(pbp, "peer_isp( %d -> %d ) ",
+			       os.peer_isp,
+			       ns.peer_isp);
+	if (ns.user_isp != os.user_isp)
+		pbp += sprintf(pbp, "user_isp( %d -> %d ) ",
+			       os.user_isp,
+			       ns.user_isp);
+	if (pbp != pb)
+		dev_info(DEV, "%s\n", pb);
+}
 
 /**
  * is_valid_state() - Returns an SS_ error code if ns is not valid
@@ -704,48 +748,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 	if (warn_sync_abort)
 		dev_warn(DEV, "%s aborted.\n", warn_sync_abort);
 
-	{
-	char *pbp, pb[300];
-	pbp = pb;
-	*pbp = 0;
-	if (ns.role != os.role)
-		pbp += sprintf(pbp, "role( %s -> %s ) ",
-			       drbd_role_str(os.role),
-			       drbd_role_str(ns.role));
-	if (ns.peer != os.peer)
-		pbp += sprintf(pbp, "peer( %s -> %s ) ",
-			       drbd_role_str(os.peer),
-			       drbd_role_str(ns.peer));
-	if (ns.conn != os.conn)
-		pbp += sprintf(pbp, "conn( %s -> %s ) ",
-			       drbd_conn_str(os.conn),
-			       drbd_conn_str(ns.conn));
-	if (ns.disk != os.disk)
-		pbp += sprintf(pbp, "disk( %s -> %s ) ",
-			       drbd_disk_str(os.disk),
-			       drbd_disk_str(ns.disk));
-	if (ns.pdsk != os.pdsk)
-		pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
-			       drbd_disk_str(os.pdsk),
-			       drbd_disk_str(ns.pdsk));
-	if (is_susp(ns) != is_susp(os))
-		pbp += sprintf(pbp, "susp( %d -> %d ) ",
-			       is_susp(os),
-			       is_susp(ns));
-	if (ns.aftr_isp != os.aftr_isp)
-		pbp += sprintf(pbp, "aftr_isp( %d -> %d ) ",
-			       os.aftr_isp,
-			       ns.aftr_isp);
-	if (ns.peer_isp != os.peer_isp)
-		pbp += sprintf(pbp, "peer_isp( %d -> %d ) ",
-			       os.peer_isp,
-			       ns.peer_isp);
-	if (ns.user_isp != os.user_isp)
-		pbp += sprintf(pbp, "user_isp( %d -> %d ) ",
-			       os.user_isp,
-			       ns.user_isp);
-	dev_info(DEV, "%s\n", pb);
-	}
+	print_state_change(mdev, os, ns, flags);
 
 	/* solve the race between becoming unconfigured,
 	 * worker doing the cleanup, and
@@ -887,7 +890,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 		ascw->done = done;
 		drbd_queue_work(&mdev->tconn->data.work, &ascw->w);
 	} else {
-		dev_warn(DEV, "Could not kmalloc an ascw\n");
+		dev_err(DEV, "Could not kmalloc an ascw\n");
 	}
 
 	return rv;
@@ -1239,21 +1242,202 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			resume_next_sg(mdev);
 	}
 
-	after_conn_state_ch(mdev->tconn, os, ns, flags);
+	after_all_state_ch(mdev->tconn, ns);
+
 	drbd_md_sync(mdev);
 }
 
-static void after_conn_state_ch(struct drbd_tconn *tconn, union drbd_state os,
-				union drbd_state ns, enum chg_state_flags flags)
+struct after_conn_state_chg_work {
+	struct drbd_work w;
+	enum drbd_conns oc;
+	union drbd_state nms; /* new, max state, over all mdevs */
+	enum chg_state_flags flags;
+};
+
+static void after_all_state_ch(struct drbd_tconn *tconn, union drbd_state ns)
+{
+	if (ns.disk == D_DISKLESS && ns.conn == C_STANDALONE && ns.role == R_SECONDARY) {
+		/* if (test_bit(DEVICE_DYING, &mdev->flags)) TODO: DEVICE_DYING functionality */
+		drbd_thread_stop_nowait(&tconn->worker);
+	}
+}
+
+static int w_after_conn_state_ch(struct drbd_work *w, int unused)
 {
+	struct after_conn_state_chg_work *acscw =
+		container_of(w, struct after_conn_state_chg_work, w);
+	struct drbd_tconn *tconn = w->tconn;
+	enum drbd_conns oc = acscw->oc;
+	union drbd_state nms = acscw->nms;
+
+	kfree(acscw);
+
 	/* Upon network configuration, we need to start the receiver */
-	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
+	if (oc == C_STANDALONE && nms.conn == C_UNCONNECTED)
 		drbd_thread_start(&tconn->receiver);
 
-	if (ns.disk == D_DISKLESS &&
-	    ns.conn == C_STANDALONE &&
-	    ns.role == R_SECONDARY) {
-		/* if (test_bit(DEVICE_DYING, &mdev->flags)) TODO: DEVICE_DYING functionality */
-		drbd_thread_stop_nowait(&tconn->worker);
+	//conn_err(tconn, STATE_FMT, STATE_ARGS("nms", nms));
+	after_all_state_ch(tconn, nms);
+
+	return 1;
+}
+
+static void print_conn_state_change(struct drbd_tconn *tconn, enum drbd_conns oc, enum drbd_conns nc)
+{
+	char *pbp, pb[300];
+	pbp = pb;
+	*pbp = 0;
+	if (nc != oc)
+		pbp += sprintf(pbp, "conn( %s -> %s ) ",
+			       drbd_conn_str(oc),
+			       drbd_conn_str(nc));
+
+	conn_info(tconn, "%s\n", pb);
+}
+
+struct _is_valid_itr_params {
+	enum chg_state_flags flags;
+	union drbd_state mask, val;
+	union drbd_state ms; /* maximal state, over all mdevs */
+	enum drbd_conns oc;
+	enum {
+		OC_UNINITIALIZED,
+		OC_CONSISTENT,
+		OC_INCONSISTENT,
+	} oc_state;
+};
+
+static int _is_valid_itr_fn(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data;
+	enum chg_state_flags flags = params->flags;
+	union drbd_state ns, os;
+	enum drbd_state_rv rv;
+
+	os = mdev->state;
+	ns = apply_mask_val(os, params->mask, params->val);
+	ns = sanitize_state(mdev, ns, NULL);
+	rv = is_valid_state(mdev, ns);
+
+	if (rv < SS_SUCCESS) {
+		/* If the old state was illegal as well, then let this happen...*/
+
+		if (is_valid_state(mdev, os) == rv)
+			rv = is_valid_soft_transition(os, ns);
+	} else
+		rv = is_valid_soft_transition(os, ns);
+
+	switch (params->oc_state) {
+	case OC_UNINITIALIZED:
+		params->oc = os.conn;
+		params->oc_state = OC_CONSISTENT;
+		break;
+	case OC_CONSISTENT:
+		if (params->oc != os.conn)
+			params->oc_state = OC_INCONSISTENT;
+		break;
+	case OC_INCONSISTENT:
+		break;
+	}
+
+	if (rv < SS_SUCCESS) {
+		if (flags & CS_VERBOSE)
+			print_st_err(mdev, os, ns, rv);
+		return rv;
+	} else
+		return 0;
+}
+
+static int _set_state_itr_fn(int vnr, void *p, void *data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *)p;
+	struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data;
+	enum chg_state_flags flags = params->flags;
+	union drbd_state os, ns, ms = params->ms;
+	enum drbd_state_rv rv;
+
+	os = mdev->state;
+	ns = apply_mask_val(os, params->mask, params->val);
+	ns = sanitize_state(mdev, ns, NULL);
+
+	rv = __drbd_set_state(mdev, ns, flags, NULL);
+
+	ms.role = max_t(enum drbd_role, mdev->state.role, ms.role);
+	ms.peer = max_t(enum drbd_role, mdev->state.peer, ms.peer);
+	ms.disk = max_t(enum drbd_role, mdev->state.disk, ms.disk);
+	ms.pdsk = max_t(enum drbd_role, mdev->state.pdsk, ms.pdsk);
+	params->ms = ms;
+
+	return 0;
+}
+
+enum drbd_state_rv
+_conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
+		    enum chg_state_flags flags)
+{
+	enum drbd_state_rv rv = SS_SUCCESS;
+	struct _is_valid_itr_params params;
+	struct after_conn_state_chg_work *acscw;
+	enum drbd_conns oc = tconn->cstate;
+
+	read_lock(&global_state_lock);
+
+	rv = is_valid_conn_transition(oc, val.conn);
+	if (rv < SS_SUCCESS)
+		goto abort;
+
+	params.flags = flags;
+	params.mask = mask;
+	params.val = val;
+	params.oc_state = OC_UNINITIALIZED;
+
+	if (!(flags & CS_HARD))
+		rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, &params);
+
+	if (rv == 0)  /* idr_for_each semantics */
+		rv = SS_SUCCESS;
+
+	if (rv < SS_SUCCESS)
+		goto abort;
+
+	if (params.oc_state == OC_CONSISTENT) {
+		oc = params.oc;
+		print_conn_state_change(tconn, oc, val.conn);
+		params.flags |= CS_NO_CSTATE_CHG;
 	}
+	tconn->cstate = val.conn;
+	params.ms.i = 0;
+	params.ms.conn = val.conn;
+	idr_for_each(&tconn->volumes, _set_state_itr_fn, &params);
+
+	acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC);
+	if (acscw) {
+		acscw->oc = oc;
+		acscw->nms = params.ms;
+		acscw->flags = flags;
+		acscw->w.cb = w_after_conn_state_ch;
+		acscw->w.tconn = tconn;
+		drbd_queue_work(&tconn->data.work, &acscw->w);
+	} else {
+		conn_err(tconn, "Could not kmalloc an acscw\n");
+	}
+
+abort:
+	read_unlock(&global_state_lock);
+
+	return rv;
+}
+
+enum drbd_state_rv
+conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
+		   enum chg_state_flags flags)
+{
+	static enum drbd_state_rv rv;
+
+	spin_lock_irq(&tconn->req_lock);
+	rv = _conn_request_state(tconn, mask, val, flags);
+	spin_unlock_irq(&tconn->req_lock);
+
+	return rv;
 }
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index 3ec26e2..d312d84 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -2,6 +2,7 @@
 #define DRBD_STATE_H
 
 struct drbd_conf;
+struct drbd_tconn;
 
 /**
  * DOC: DRBD State macros
@@ -61,6 +62,7 @@ enum chg_state_flags {
 	CS_WAIT_COMPLETE = 4,
 	CS_SERIALIZE    = 8,
 	CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
+	CS_NO_CSTATE_CHG = 16, /* Do not display changes in cstate. Internal to drbd_state.c */
 };
 
 extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
@@ -79,6 +81,14 @@ extern enum drbd_state_rv __drbd_set_state(struct drbd_conf *, union drbd_state,
 extern void print_st_err(struct drbd_conf *, union drbd_state,
 			union drbd_state, int);
 
+enum drbd_state_rv
+_conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
+		    enum chg_state_flags flags);
+
+enum drbd_state_rv
+conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
+		   enum chg_state_flags flags);
+
 extern void drbd_resume_al(struct drbd_conf *mdev);
 
 /**
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 8539df2..eee017d 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1720,11 +1720,10 @@ int drbd_worker(struct drbd_thread *thi)
 		list_del_init(&w->list);
 		spin_unlock_irq(&tconn->data.work.q_lock);
 
-		if (!w->cb(w, tconn->volume0->state.conn < C_CONNECTED)) {
+		if (!w->cb(w, tconn->cstate < C_WF_REPORT_PARAMS)) {
 			/* dev_warn(DEV, "worker: a callback failed! \n"); */
-			if (tconn->volume0->state.conn >= C_CONNECTED)
-				drbd_force_state(tconn->volume0,
-						 NS(conn, C_NETWORK_FAILURE));
+			if (tconn->cstate >= C_WF_REPORT_PARAMS)
+				conn_request_state(tconn, NS(conn, C_NETWORK_FAILURE), CS_HARD);
 		}
 	}
 
-- 
1.7.4.1


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

* [PATCH 111/118] drbd: Removed drbd_state_lock() and drbd_state_unlock()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (109 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 110/118] drbd: Killed volume0; last step of multi-volume-enablement Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 112/118] drbd: Introduced tconn->cstate_mutex Philipp Reisner
                   ` (8 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

The lock they constructed is only taken when the state_mutex
was already taken. It is superficial.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0ea0b15..d5e45c2 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -763,7 +763,6 @@ enum {
 	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
 	MD_DIRTY,		/* current uuids and flags not yet on disk */
 	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
-	CLUSTER_ST_CHANGE,	/* Cluster wide state change going on... */
 	CL_ST_CHG_SUCCESS,
 	CL_ST_CHG_FAIL,
 	CRASHED_PRIMARY,	/* This node was a crashed primary.
@@ -1663,23 +1662,6 @@ static inline int drbd_ee_has_active_page(struct drbd_peer_request *peer_req)
 	return 0;
 }
 
-
-
-
-
-
-static inline void drbd_state_lock(struct drbd_conf *mdev)
-{
-	wait_event(mdev->misc_wait,
-		   !test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags));
-}
-
-static inline void drbd_state_unlock(struct drbd_conf *mdev)
-{
-	clear_bit(CLUSTER_ST_CHANGE, &mdev->flags);
-	wake_up(&mdev->misc_wait);
-}
-
 static inline enum drbd_state_rv
 _drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
 		enum chg_state_flags flags, struct completion *done)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index f755134..6a30180 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3170,7 +3170,8 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
 	   ongoing cluster wide state change is finished. That is important if
 	   we are primary and are detaching from our disk. We need to see the
 	   new disk state... */
-	wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags));
+	mutex_lock(&mdev->state_mutex);
+	mutex_unlock(&mdev->state_mutex);
 	if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT)
 		updated_uuids |= drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]);
 
@@ -3221,7 +3222,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
 	val.i = be32_to_cpu(p->val);
 
 	if (test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags) &&
-	    test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) {
+	    mutex_is_locked(&mdev->state_mutex)) {
 		drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG);
 		return true;
 	}
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 405ed12..bb05d67 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -184,9 +184,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 			goto abort;
 		}
 
-		drbd_state_lock(mdev);
 		if (!drbd_send_state_req(mdev, mask, val)) {
-			drbd_state_unlock(mdev);
 			rv = SS_CW_FAILED_BY_PEER;
 			if (f & CS_VERBOSE)
 				print_st_err(mdev, os, ns, rv);
@@ -197,7 +195,6 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 			(rv = _req_st_cond(mdev, mask, val)));
 
 		if (rv < SS_SUCCESS) {
-			drbd_state_unlock(mdev);
 			if (f & CS_VERBOSE)
 				print_st_err(mdev, os, ns, rv);
 			goto abort;
@@ -205,7 +202,6 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 		spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 		ns = apply_mask_val(mdev->state, mask, val);
 		rv = _drbd_set_state(mdev, ns, f, &done);
-		drbd_state_unlock(mdev);
 	} else {
 		rv = _drbd_set_state(mdev, ns, f, &done);
 	}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index eee017d..e844871 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1536,21 +1536,21 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 	}
 
 	if (current == mdev->tconn->worker.task) {
-		/* The worker should not sleep waiting for drbd_state_lock(),
+		/* The worker should not sleep waiting for state_mutex,
 		   that can take long */
-		if (test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags)) {
+		if (!mutex_trylock(&mdev->state_mutex)) {
 			set_bit(B_RS_H_DONE, &mdev->flags);
 			mdev->start_resync_timer.expires = jiffies + HZ/5;
 			add_timer(&mdev->start_resync_timer);
 			return;
 		}
 	} else {
-		drbd_state_lock(mdev);
+		mutex_lock(&mdev->state_mutex);
 	}
 	clear_bit(B_RS_H_DONE, &mdev->flags);
 
 	if (!get_ldev_if_state(mdev, D_NEGOTIATING)) {
-		drbd_state_unlock(mdev);
+		mutex_unlock(&mdev->state_mutex);
 		return;
 	}
 
@@ -1639,7 +1639,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 		drbd_md_sync(mdev);
 	}
 	put_ldev(mdev);
-	drbd_state_unlock(mdev);
+	mutex_unlock(&mdev->state_mutex);
 }
 
 static int _worker_dying(int vnr, void *p, void *data)
-- 
1.7.4.1


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

* [PATCH 112/118] drbd: Introduced tconn->cstate_mutex
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (110 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 111/118] drbd: Removed drbd_state_lock() and drbd_state_unlock() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 113/118] drbd: Implemented conn_send_state_req() Philipp Reisner
                   ` (7 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

In compatibility mode with old DRBDs, use that as the state_mutex
as well.

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     |    4 +++-
 drivers/block/drbd/drbd_nl.c       |    8 ++++----
 drivers/block/drbd/drbd_receiver.c |   11 ++++++++---
 drivers/block/drbd/drbd_state.c    |    4 ++--
 drivers/block/drbd/drbd_worker.c   |    8 ++++----
 6 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index d5e45c2..a321bf9 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -916,8 +916,9 @@ enum {
 struct drbd_tconn {			/* is a resource from the config file */
 	char *name;			/* Resource name */
 	struct list_head all_tconn;	/* List of all drbd_tconn, prot by global_state_lock */
-	struct idr volumes;             /* <tconn, vnr> to mdev mapping */
-	enum drbd_conns cstate;        /* Only C_STANDALONE to C_WF_REPORT_PARAMS */
+	struct idr volumes;		/* <tconn, vnr> to mdev mapping */
+	enum drbd_conns cstate;		/* Only C_STANDALONE to C_WF_REPORT_PARAMS */
+	struct mutex cstate_mutex;	/* Protects graceful disconnects */
 
 	unsigned long flags;
 	struct net_conf *net_conf;	/* protected by get_net_conf() and put_net_conf() */
@@ -1079,7 +1080,8 @@ struct drbd_conf {
 	unsigned long comm_bm_set; /* communicated number of set bits. */
 	struct bm_io_work bm_io_work;
 	u64 ed_uuid; /* UUID of the exposed data */
-	struct mutex state_mutex;
+	struct mutex own_state_mutex;
+	struct mutex *state_mutex; /* either own_state_mutex or mdev->tconn->cstate_mutex */
 	char congestion_reason;  /* Why we where congested... */
 	atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
 	atomic_t rs_sect_ev; /* for submitted resync data rate, both */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 2c1df75..adfef15 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1813,7 +1813,8 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 	atomic_set(&mdev->ap_in_flight, 0);
 
 	mutex_init(&mdev->md_io_mutex);
-	mutex_init(&mdev->state_mutex);
+	mutex_init(&mdev->own_state_mutex);
+	mdev->state_mutex = &mdev->own_state_mutex;
 
 	spin_lock_init(&mdev->al_lock);
 	spin_lock_init(&mdev->peer_seq_lock);
@@ -2201,6 +2202,7 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 		goto fail;
 
 	tconn->cstate = C_STANDALONE;
+	mutex_init(&tconn->cstate_mutex);
 	spin_lock_init(&tconn->req_lock);
 	atomic_set(&tconn->net_cnt, 0);
 	init_waitqueue_head(&tconn->net_cnt_wait);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index eeb284a..3d8e631 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -320,7 +320,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 	if (new_role == R_PRIMARY)
 		request_ping(mdev->tconn); /* Detect a dead peer ASAP */
 
-	mutex_lock(&mdev->state_mutex);
+	mutex_lock(mdev->state_mutex);
 
 	mask.i = 0; mask.role = R_MASK;
 	val.i  = 0; val.role  = new_role;
@@ -439,7 +439,7 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 
 	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
  fail:
-	mutex_unlock(&mdev->state_mutex);
+	mutex_unlock(mdev->state_mutex);
 	return rv;
 }
 
@@ -2162,7 +2162,7 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 		return 0;
 	}
 
-	mutex_lock(&mdev->state_mutex); /* Protects us against serialized state changes. */
+	mutex_lock(mdev->state_mutex); /* Protects us against serialized state changes. */
 
 	if (!get_ldev(mdev)) {
 		retcode = ERR_NO_DISK;
@@ -2204,7 +2204,7 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 out_dec:
 	put_ldev(mdev);
 out:
-	mutex_unlock(&mdev->state_mutex);
+	mutex_unlock(mdev->state_mutex);
 
 	reply->ret_code = retcode;
 	return 0;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6a30180..86d1e9b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -753,6 +753,10 @@ static int drbd_connected(int vnr, void *p, void *data)
 	atomic_set(&mdev->packet_seq, 0);
 	mdev->peer_seq = 0;
 
+	mdev->state_mutex = mdev->tconn->agreed_pro_version < 100 ?
+		&mdev->tconn->cstate_mutex :
+		&mdev->own_state_mutex;
+
 	ok &= drbd_send_sync_param(mdev, &mdev->sync_conf);
 	ok &= drbd_send_sizes(mdev, 0, 0);
 	ok &= drbd_send_uuids(mdev);
@@ -760,6 +764,7 @@ static int drbd_connected(int vnr, void *p, void *data)
 	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
 	clear_bit(RESIZE_PENDING, &mdev->flags);
 
+
 	return !ok;
 }
 
@@ -3170,8 +3175,8 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
 	   ongoing cluster wide state change is finished. That is important if
 	   we are primary and are detaching from our disk. We need to see the
 	   new disk state... */
-	mutex_lock(&mdev->state_mutex);
-	mutex_unlock(&mdev->state_mutex);
+	mutex_lock(mdev->state_mutex);
+	mutex_unlock(mdev->state_mutex);
 	if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT)
 		updated_uuids |= drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]);
 
@@ -3222,7 +3227,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
 	val.i = be32_to_cpu(p->val);
 
 	if (test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags) &&
-	    mutex_is_locked(&mdev->state_mutex)) {
+	    mutex_is_locked(mdev->state_mutex)) {
 		drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG);
 		return true;
 	}
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index bb05d67..29308e0 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -163,7 +163,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 	init_completion(&done);
 
 	if (f & CS_SERIALIZE)
-		mutex_lock(&mdev->state_mutex);
+		mutex_lock(mdev->state_mutex);
 
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
@@ -215,7 +215,7 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask,
 
 abort:
 	if (f & CS_SERIALIZE)
-		mutex_unlock(&mdev->state_mutex);
+		mutex_unlock(mdev->state_mutex);
 
 	return rv;
 }
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index e844871..9a9a00e 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1538,19 +1538,19 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 	if (current == mdev->tconn->worker.task) {
 		/* The worker should not sleep waiting for state_mutex,
 		   that can take long */
-		if (!mutex_trylock(&mdev->state_mutex)) {
+		if (!mutex_trylock(mdev->state_mutex)) {
 			set_bit(B_RS_H_DONE, &mdev->flags);
 			mdev->start_resync_timer.expires = jiffies + HZ/5;
 			add_timer(&mdev->start_resync_timer);
 			return;
 		}
 	} else {
-		mutex_lock(&mdev->state_mutex);
+		mutex_lock(mdev->state_mutex);
 	}
 	clear_bit(B_RS_H_DONE, &mdev->flags);
 
 	if (!get_ldev_if_state(mdev, D_NEGOTIATING)) {
-		mutex_unlock(&mdev->state_mutex);
+		mutex_unlock(mdev->state_mutex);
 		return;
 	}
 
@@ -1639,7 +1639,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 		drbd_md_sync(mdev);
 	}
 	put_ldev(mdev);
-	mutex_unlock(&mdev->state_mutex);
+	mutex_unlock(mdev->state_mutex);
 }
 
 static int _worker_dying(int vnr, void *p, void *data)
-- 
1.7.4.1


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

* [PATCH 113/118] drbd: Implemented conn_send_state_req()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (111 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 112/118] drbd: Introduced tconn->cstate_mutex Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 114/118] drbd: Global_state_lock not necessary here Philipp Reisner
                   ` (6 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index a321bf9..35e7303 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -220,8 +220,10 @@ enum drbd_packet {
 	P_DELAY_PROBE         = 0x27, /* is used on BOTH sockets */
 	P_OUT_OF_SYNC         = 0x28, /* Mark as out of sync (Outrunning), data socket */
 	P_RS_CANCEL           = 0x29, /* meta: Used to cancel RS_DATA_REQUEST packet by SyncSource */
+	P_CONN_ST_CHG_REQ     = 0x2a, /* data sock: Connection wide state request */
+	P_CONN_ST_CHG_REPLY   = 0x2b, /* meta sock: Connection side state req reply */
 
-	P_MAX_CMD	      = 0x2A,
+	P_MAX_CMD	      = 0x2c,
 	P_MAY_IGNORE	      = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */
 	P_MAX_OPT_CMD	      = 0x101,
 
@@ -1176,6 +1178,8 @@ extern int drbd_send_uuids(struct drbd_conf *mdev);
 extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev);
 extern int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev);
 extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags);
+extern int _conn_send_state_req(struct drbd_tconn *, int vnr, enum drbd_packet cmd,
+				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 socket *sock,
@@ -1895,6 +1899,19 @@ static inline int drbd_send_ping_ack(struct drbd_tconn *tconn)
 	return conn_send_cmd(tconn, 0, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h));
 }
 
+static inline int drbd_send_state_req(struct drbd_conf *mdev,
+				      union drbd_state mask, union drbd_state val)
+{
+	return _conn_send_state_req(mdev->tconn, mdev->vnr, P_STATE_CHG_REQ, mask, val);
+}
+
+static inline int conn_send_state_req(struct drbd_tconn *tconn,
+				      union drbd_state mask, union drbd_state val)
+{
+	enum drbd_packet cmd = tconn->agreed_pro_version < 100 ? P_STATE_CHG_REQ : P_CONN_ST_CHG_REQ;
+	return _conn_send_state_req(tconn, 0, cmd, mask, val);
+}
+
 static inline void drbd_thread_stop(struct drbd_thread *thi)
 {
 	_drbd_thread_stop(thi, false, true);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index adfef15..c41d93c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -982,15 +982,15 @@ int drbd_send_state(struct drbd_conf *mdev)
 	return ok;
 }
 
-int drbd_send_state_req(struct drbd_conf *mdev,
-	union drbd_state mask, union drbd_state val)
+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);
 
-	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_STATE_CHG_REQ, &p.head, sizeof(p));
+	return conn_send_cmd(tconn, vnr, USE_DATA_SOCKET, cmd, &p.head, sizeof(p));
 }
 
 int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 29308e0..db2aee9 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -37,9 +37,7 @@ struct after_state_chg_work {
 	struct completion *done;
 };
 
-
 extern void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
-int drbd_send_state_req(struct drbd_conf *, union drbd_state, union drbd_state);
 static int w_after_state_ch(struct drbd_work *w, int unused);
 static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
 			   union drbd_state ns, enum chg_state_flags flags);
-- 
1.7.4.1


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

* [PATCH 114/118] drbd: Global_state_lock not necessary here...
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (112 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 113/118] drbd: Implemented conn_send_state_req() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 115/118] drbd: Implemented conn_send_sr_reply() Philipp Reisner
                   ` (5 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index db2aee9..81f66b3 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1375,8 +1375,6 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	struct after_conn_state_chg_work *acscw;
 	enum drbd_conns oc = tconn->cstate;
 
-	read_lock(&global_state_lock);
-
 	rv = is_valid_conn_transition(oc, val.conn);
 	if (rv < SS_SUCCESS)
 		goto abort;
@@ -1418,8 +1416,6 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	}
 
 abort:
-	read_unlock(&global_state_lock);
-
 	return rv;
 }
 
-- 
1.7.4.1


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

* [PATCH 115/118] drbd: Implemented conn_send_sr_reply()
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (113 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 114/118] drbd: Global_state_lock not necessary here Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 116/118] drbd: Implemented receiving of P_CONN_ST_CHG_REPLY Philipp Reisner
                   ` (4 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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 |   10 ++++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 35e7303..4fc1b0db 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1216,6 +1216,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 int _drbd_send_bitmap(struct drbd_conf *mdev);
 extern int 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 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);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c41d93c..c4ac636 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1002,6 +1002,16 @@ int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode)
 	return drbd_send_cmd(mdev, USE_META_SOCKET, P_STATE_CHG_REPLY, &p.head, sizeof(p));
 }
 
+int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
+{
+	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, USE_META_SOCKET, cmd, &p.head, sizeof(p));
+}
+
 int fill_bitmap_rle_bits(struct drbd_conf *mdev,
 	struct p_compressed_bm *p,
 	struct bm_xfer_ctx *c)
-- 
1.7.4.1


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

* [PATCH 116/118] drbd: Implemented receiving of P_CONN_ST_CHG_REPLY
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (114 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 115/118] drbd: Implemented conn_send_sr_reply() Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 117/118] drbd: implemented receiving of P_CONN_ST_CHG_REQ Philipp Reisner
                   ` (3 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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_receiver.c |   28 ++++++++++++++++++++--------
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 4fc1b0db..ed3d498 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -913,6 +913,8 @@ enum {
 	SEND_PING,		/* whether asender should send a ping asap */
 	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
 	GOT_PING_ACK,		/* set when we receive a ping_ack packet, ping_wait gets woken */
+	CONN_WD_ST_CHG_OKAY,
+	CONN_WD_ST_CHG_FAIL,
 };
 
 struct drbd_tconn {			/* is a resource from the config file */
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 86d1e9b..bdd3f00 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -4268,18 +4268,29 @@ int drbdd_init(struct drbd_thread *thi)
 static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packet cmd)
 {
 	struct p_req_state_reply *p = &mdev->tconn->meta.rbuf.req_state_reply;
+	struct drbd_tconn *tconn = mdev->tconn;
 
 	int retcode = be32_to_cpu(p->retcode);
 
-	if (retcode >= SS_SUCCESS) {
-		set_bit(CL_ST_CHG_SUCCESS, &mdev->flags);
-	} else {
-		set_bit(CL_ST_CHG_FAIL, &mdev->flags);
-		dev_err(DEV, "Requested state change failed by peer: %s (%d)\n",
-		    drbd_set_st_err_str(retcode), retcode);
+	if (cmd == P_STATE_CHG_REPLY) {
+		if (retcode >= SS_SUCCESS) {
+			set_bit(CL_ST_CHG_SUCCESS, &mdev->flags);
+		} else {
+			set_bit(CL_ST_CHG_FAIL, &mdev->flags);
+			dev_err(DEV, "Requested state change failed by peer: %s (%d)\n",
+				drbd_set_st_err_str(retcode), retcode);
+		}
+		wake_up(&mdev->state_wait);
+	} else /* conn == P_CONN_ST_CHG_REPLY */ {
+		if (retcode >= SS_SUCCESS) {
+			set_bit(CONN_WD_ST_CHG_OKAY, &tconn->flags);
+		} else {
+			set_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags);
+			conn_err(tconn, "Requested state change failed by peer: %s (%d)\n",
+				 drbd_set_st_err_str(retcode), retcode);
+		}
+		wake_up(&tconn->ping_wait);
 	}
-	wake_up(&mdev->state_wait);
-
 	return true;
 }
 
@@ -4556,6 +4567,7 @@ static struct asender_cmd *get_asender_cmd(int cmd)
 	[P_RS_IS_IN_SYNC]   = { sizeof(struct p_block_ack), got_IsInSync },
 	[P_DELAY_PROBE]     = { sizeof(struct p_delay_probe93), got_skip },
 	[P_RS_CANCEL]       = { sizeof(struct p_block_ack), got_NegRSDReply},
+	[P_CONN_ST_CHG_REPLY]={ sizeof(struct p_req_state_reply), got_RqSReply },
 	[P_MAX_CMD]	    = { 0, NULL },
 	};
 	if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL)
-- 
1.7.4.1


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

* [PATCH 117/118] drbd: implemented receiving of P_CONN_ST_CHG_REQ
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (115 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 116/118] drbd: Implemented receiving of P_CONN_ST_CHG_REPLY Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-25 15:08 ` [PATCH 118/118] drbd: Implemented connection wide state changes Philipp Reisner
                   ` (2 subsequent siblings)
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

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

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bdd3f00..e346245 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3235,9 +3235,14 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
 	mask = convert_state(mask);
 	val = convert_state(val);
 
-	rv = drbd_change_state(mdev, CS_VERBOSE, mask, val);
+	if (cmd == P_CONN_ST_CHG_REQ) {
+		rv = conn_request_state(mdev->tconn, mask, val, CS_VERBOSE | CS_LOCAL_ONLY);
+		conn_send_sr_reply(mdev->tconn, rv);
+	} else {
+		rv = drbd_change_state(mdev, CS_VERBOSE, mask, val);
+		drbd_send_sr_reply(mdev, rv);
+	}
 
-	drbd_send_sr_reply(mdev, rv);
 	drbd_md_sync(mdev);
 
 	return true;
@@ -3771,6 +3776,7 @@ static struct data_cmd drbd_cmd_handler[] = {
 	[P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest },
 	[P_DELAY_PROBE]     = { 0, sizeof(struct p_delay_probe93), receive_skip },
 	[P_OUT_OF_SYNC]     = { 0, sizeof(struct p_block_desc), receive_out_of_sync },
+	[P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_state },
 	/* anything missing from this table is in
 	 * the asender_tbl, see get_asender_cmd */
 	[P_MAX_CMD]	    = { 0, 0, NULL },
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index d312d84..5fdbdf0 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -63,6 +63,7 @@ enum chg_state_flags {
 	CS_SERIALIZE    = 8,
 	CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
 	CS_NO_CSTATE_CHG = 16, /* Do not display changes in cstate. Internal to drbd_state.c */
+	CS_LOCAL_ONLY = 32, /* Do not consider a device pair wide state change */
 };
 
 extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
-- 
1.7.4.1


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

* [PATCH 118/118] drbd: Implemented connection wide state changes
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (116 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 117/118] drbd: implemented receiving of P_CONN_ST_CHG_REQ Philipp Reisner
@ 2011-08-25 15:08 ` Philipp Reisner
  2011-08-26  1:30 ` [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd David Miller
       [not found] ` <CAGpXXZKem-uEdF4SyUgpQFV6=d5Vo3v9p3wmcaygAKa4w4x01w@mail.gmail.com>
  119 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-25 15:08 UTC (permalink / raw)
  To: linux-kernel, Jens Axboe; +Cc: drbd-dev

That is used for graceful disconnect only

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
 drivers/block/drbd/drbd_nl.c    |   28 +++++++++---------
 drivers/block/drbd/drbd_state.c |   62 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 3d8e631..d6832f8 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1572,6 +1572,7 @@ fail:
 static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 			      struct drbd_nl_cfg_reply *reply)
 {
+	struct drbd_tconn *tconn = mdev->tconn;
 	int retcode;
 	struct disconnect dc;
 
@@ -1582,30 +1583,29 @@ static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 	}
 
 	if (dc.force) {
-		spin_lock_irq(&mdev->tconn->req_lock);
-		if (mdev->state.conn >= C_WF_CONNECTION)
-			_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), CS_HARD, NULL);
-		spin_unlock_irq(&mdev->tconn->req_lock);
+		spin_lock_irq(&tconn->req_lock);
+		if (tconn->cstate >= C_WF_CONNECTION)
+			_conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
+		spin_unlock_irq(&tconn->req_lock);
 		goto done;
 	}
 
-	retcode = _drbd_request_state(mdev, NS(conn, C_DISCONNECTING), CS_ORDERED);
+	retcode = conn_request_state(tconn, NS(conn, C_DISCONNECTING), 0);
 
 	if (retcode == SS_NOTHING_TO_DO)
 		goto done;
 	else if (retcode == SS_ALREADY_STANDALONE)
 		goto done;
 	else if (retcode == SS_PRIMARY_NOP) {
-		/* Our statche checking code wants to see the peer outdated. */
-		retcode = drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
-						      pdsk, D_OUTDATED));
+		/* Our state checking code wants to see the peer outdated. */
+		retcode = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
+							pdsk, D_OUTDATED), CS_VERBOSE);
 	} else if (retcode == SS_CW_FAILED_BY_PEER) {
 		/* The peer probably wants to see us outdated. */
-		retcode = _drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
-							disk, D_OUTDATED),
-					      CS_ORDERED);
+		retcode = conn_request_state(tconn, NS2(conn, C_DISCONNECTING,
+							disk, D_OUTDATED), 0);
 		if (retcode == SS_IS_DISKLESS || retcode == SS_LOWER_THAN_OUTDATED) {
-			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
 			retcode = SS_SUCCESS;
 		}
 	}
@@ -1613,8 +1613,8 @@ static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 	if (retcode < SS_SUCCESS)
 		goto fail;
 
-	if (wait_event_interruptible(mdev->state_wait,
-				     mdev->state.conn != C_DISCONNECTING)) {
+	if (wait_event_interruptible(tconn->ping_wait,
+				     tconn->cstate != C_DISCONNECTING)) {
 		/* Do not test for mdev->state.conn == C_STANDALONE, since
 		   someone else might connect us in the mean time! */
 		retcode = ERR_INTR;
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 81f66b3..61c65f5 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1366,6 +1366,62 @@ static int _set_state_itr_fn(int vnr, void *p, void *data)
 	return 0;
 }
 
+static enum drbd_state_rv
+_conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val)
+{
+	struct _is_valid_itr_params params;
+	enum drbd_conns oc = tconn->cstate;
+	enum drbd_state_rv rv;
+
+	if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &tconn->flags))
+		return SS_CW_SUCCESS;
+
+	if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags))
+		return SS_CW_FAILED_BY_PEER;
+
+	params.flags = CS_NO_CSTATE_CHG; /* öö think */
+	params.mask = mask;
+	params.val = val;
+
+	spin_lock_irq(&tconn->req_lock);
+	rv = oc != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR;
+
+	if (rv == SS_UNKNOWN_ERROR)
+		rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, &params);
+
+	if (rv == 0)  /* idr_for_each semantics */
+		rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
+
+	spin_unlock_irq(&tconn->req_lock);
+
+	return rv;
+}
+
+static enum drbd_state_rv
+conn_cl_wide(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
+	     enum chg_state_flags f)
+{
+	enum drbd_state_rv rv;
+
+	spin_unlock_irq(&tconn->req_lock);
+	mutex_lock(&tconn->cstate_mutex);
+
+	if (!conn_send_state_req(tconn, mask, val)) {
+		rv = SS_CW_FAILED_BY_PEER;
+		/* if (f & CS_VERBOSE)
+		   print_st_err(mdev, os, ns, rv); */
+		goto abort;
+	}
+
+	wait_event(tconn->ping_wait, (rv = _conn_rq_cond(tconn, mask, val)));
+
+abort:
+	mutex_unlock(&tconn->cstate_mutex);
+	spin_lock_irq(&tconn->req_lock);
+
+	return rv;
+}
+
 enum drbd_state_rv
 _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val,
 		    enum chg_state_flags flags)
@@ -1393,6 +1449,12 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
 	if (rv < SS_SUCCESS)
 		goto abort;
 
+	if (oc == C_WF_REPORT_PARAMS && val.conn == C_DISCONNECTING && !(flags & CS_LOCAL_ONLY)) {
+		rv = conn_cl_wide(tconn, mask, val, flags);
+		if (rv < SS_SUCCESS)
+			goto abort;
+	}
+
 	if (params.oc_state == OC_CONSISTENT) {
 		oc = params.oc;
 		print_conn_state_change(tconn, oc, val.conn);
-- 
1.7.4.1


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

* Re: [Drbd-dev] [PATCH 016/118] drbd: Add read_requests tree
  2011-08-25 15:07 ` [PATCH 016/118] drbd: Add read_requests tree Philipp Reisner
@ 2011-08-25 18:02   ` Pawel Jakub Dawidek
  2011-08-29 11:42     ` Philipp Reisner
  0 siblings, 1 reply; 132+ messages in thread
From: Pawel Jakub Dawidek @ 2011-08-25 18:02 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]

On Thu, Aug 25, 2011 at 05:07:12PM +0200, Philipp Reisner wrote:
> From: Andreas Gruenbacher <agruen@linbit.com>
> 
> We do not do collision detection for read requests, but we still need to
> look up the request objects when we receive a package over the network.
> Using the same data structure for read and write requests results in
> simpler code once the tl_hash and app_reads_hash tables are removed.
> 
> 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_req.c  |   13 ++++++++++---
>  3 files changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
> index 0583713..fe15319 100644
> --- a/drivers/block/drbd/drbd_int.h
> +++ b/drivers/block/drbd/drbd_int.h
> @@ -1020,6 +1020,7 @@ struct drbd_conf {
>  	unsigned int tl_hash_s;
>  
>  	/* Interval tree of pending local write requests */
> +	struct rb_root read_requests;
>  	struct rb_root write_requests;

Looks like the comment needs updating.

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://yomoli.com

[-- Attachment #2: Type: application/pgp-signature, Size: 196 bytes --]

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

* Re: [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections
  2011-08-25 15:08 ` [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections Philipp Reisner
@ 2011-08-25 18:16   ` Joe Perches
  2011-08-29 11:42     ` [Drbd-dev] " Philipp Reisner
  0 siblings, 1 reply; 132+ messages in thread
From: Joe Perches @ 2011-08-25 18:16 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: linux-kernel, Jens Axboe, drbd-dev

On Thu, 2011-08-25 at 17:08 +0200, Philipp Reisner wrote:
> 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 |   16 +++++++++++++++-
>  2 files changed, 24 insertions(+), 1 deletions(-)

Couple of issues with this patch.

> diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
[]
> @@ -102,6 +102,15 @@ struct drbd_tconn;
[]
> +extern void conn_printk(const char *level, struct drbd_tconn *tconn, const char *fmt, ...);

This should be 

extern __attribute__((format (printf, 3, 4)))
void conn_printk(const char *level, struct drbd_tconn *tconn, const char  *fmt, ...);

to have gcc validate the printf format and arguments.

> diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
[]
> @@ -170,6 +170,18 @@ int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins)
>  
>  #endif
>  
> +/* printk functions for connections
> + */
> +void conn_printk(const char *level, struct drbd_tconn *tconn, const char *fmt, ...)
> +{
> +	va_list args;
> +
> +	printk("%sd-con %s: ", level, tconn->name);
> +	va_start(args, fmt);
> +	vprintk(fmt, args);
> +	va_end(args);

And using printk then vprintk is susceptible
to another thread interleaving a different
message between the printk and the vprintk.

Using struct va_format and %pV is better
because no message interleaving is possible.

ie:

void conn_printk(const char *level, struct drbd_tconn *tconn, const char *fmt, ...)
{
	struct va_format vaf;
	va_list args;

	va_start(args, fmt);

	vaf.fmt = fmt;
	vaf.va = &args;

	printk("%sd-con %s: %pV", level, tconn->name, &vaf);

	va_end(args);
}


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

* Re: [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
                   ` (117 preceding siblings ...)
  2011-08-25 15:08 ` [PATCH 118/118] drbd: Implemented connection wide state changes Philipp Reisner
@ 2011-08-26  1:30 ` David Miller
       [not found] ` <CAGpXXZKem-uEdF4SyUgpQFV6=d5Vo3v9p3wmcaygAKa4w4x01w@mail.gmail.com>
  119 siblings, 0 replies; 132+ messages in thread
From: David Miller @ 2011-08-26  1:30 UTC (permalink / raw)
  To: philipp.reisner; +Cc: linux-kernel, axboe, drbd-dev


Please do not ever post such an enourmous number of patches at one
time.  Instead, break up your submittion into more manageable sets of
patches, say 10 or so at a time.

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

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
       [not found] ` <CAGpXXZKem-uEdF4SyUgpQFV6=d5Vo3v9p3wmcaygAKa4w4x01w@mail.gmail.com>
@ 2011-08-26 13:54   ` Lars Ellenberg
  2011-08-26 15:18     ` Kyle Moffett
  2011-08-29 11:46   ` Philipp Reisner
  1 sibling, 1 reply; 132+ messages in thread
From: Lars Ellenberg @ 2011-08-26 13:54 UTC (permalink / raw)
  To: Greg Freemyer; +Cc: Philipp Reisner, Jens Axboe, linux-kernel, drbd-dev

On Fri, Aug 26, 2011 at 09:20:51AM -0400, Greg Freemyer wrote:
> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
> philipp.reisner@linbit.com> wrote:
> 
> > This the first request for review of drbd-8.4. The complete set has
> > 500 patches. In this first series there are only 118 of these.
> >
> >
> Lars,
> 
> I've only taken a quick glance, but is drbd functional between applying each
> patch?
>
> It doesn't look like it to me, but I didn't look that close.  I also saw at
> least one patch that introduced a new function with no caller to test it.
> 
> The idea is that a patch series leave a testable / functional kernel after
> each patch in the series is applied sequentially.
>
> 
> That is the only way git bisect can do its job.

Very likely DRBD will not always be completely functional between
any arbitrary two of these patches.

The kernel as such will still be bisectable "just fine".

However if you hunt for DRBD internal bugs, "blindly" bisecting through
this pile of patches will not be too useful.

> ie. Introducing a new function but no new caller makes a change, but there
> is no way to test it.  Therefore there is no real value in not merging that
> patch with one that has the new call in it.

Right.


-- 
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com

DRBD® and LINBIT® are registered trademarks of LINBIT, Austria.

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

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-26 13:54   ` [Drbd-dev] " Lars Ellenberg
@ 2011-08-26 15:18     ` Kyle Moffett
  2011-08-29 11:51       ` Philipp Reisner
  0 siblings, 1 reply; 132+ messages in thread
From: Kyle Moffett @ 2011-08-26 15:18 UTC (permalink / raw)
  To: Greg Freemyer, Philipp Reisner, Jens Axboe, linux-kernel, drbd-dev

On Fri, Aug 26, 2011 at 09:54, Lars Ellenberg <lars.ellenberg@linbit.com> wrote:
> On Fri, Aug 26, 2011 at 09:20:51AM -0400, Greg Freemyer wrote:
>> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
>> philipp.reisner@linbit.com> wrote:
>>
>> > This the first request for review of drbd-8.4. The complete set has
>> > 500 patches. In this first series there are only 118 of these.
>>
>> I've only taken a quick glance, but is drbd functional between applying each
>> patch?
>>
>> It doesn't look like it to me, but I didn't look that close.  I also saw at
>> least one patch that introduced a new function with no caller to test it.
>>
>> The idea is that a patch series leave a testable / functional kernel after
>> each patch in the series is applied sequentially.
>>
>> That is the only way git bisect can do its job.
>
> Very likely DRBD will not always be completely functional between
> any arbitrary two of these patches.
>
> The kernel as such will still be bisectable "just fine".

No.

That's not the way that kernel development works.

Besides which, that's not the way that "git bisect" works.

For example, say I have a driver bug that happens to be triggering
on my server which also happens to use GFS on DRBD.  I try to
bisect the bug and it happens to pick a commit right in the middle
of this DRBD branch.

Suddenly DRBD is unusable or corrupting data or something, which
is unacceptable for an unrelated bisection of a driver bug.

So if you want these patches merged into the kernel, you need to
do them properly as per Documentation/SubmittingPatches.

Cheers,
Kyle Moffett

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

* Re: [Drbd-dev] [PATCH 016/118] drbd: Add read_requests tree
  2011-08-25 18:02   ` [Drbd-dev] " Pawel Jakub Dawidek
@ 2011-08-29 11:42     ` Philipp Reisner
  0 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 11:42 UTC (permalink / raw)
  To: Pawel Jakub Dawidek, Jens Axboe, linux-kernel; +Cc: drbd-dev

Am Donnerstag, 25. August 2011, 20:02:44 schrieb Pawel Jakub Dawidek:
> On Thu, Aug 25, 2011 at 05:07:12PM +0200, Philipp Reisner wrote:
> > From: Andreas Gruenbacher <agruen@linbit.com>
> > 
> > We do not do collision detection for read requests, but we still need to
> > look up the request objects when we receive a package over the network.
> > Using the same data structure for read and write requests results in
> > simpler code once the tl_hash and app_reads_hash tables are removed.
> > 
> > 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_req.c  |   13 ++++++++++---
> >  3 files changed, 12 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/block/drbd/drbd_int.h
> > b/drivers/block/drbd/drbd_int.h index 0583713..fe15319 100644
> > --- a/drivers/block/drbd/drbd_int.h
> > +++ b/drivers/block/drbd/drbd_int.h
> > @@ -1020,6 +1020,7 @@ struct drbd_conf {
> > 
> >  	unsigned int tl_hash_s;
> >  	
> >  	/* Interval tree of pending local write requests */
> > 
> > +	struct rb_root read_requests;
> > 
> >  	struct rb_root write_requests;
> 
> Looks like the comment needs updating.

Ok, new edition of the patch:

>From dac1389ccc273b5486f2931c64c8e1672f233727 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@linbit.com>
Date: Fri, 21 Jan 2011 17:18:39 +0100
Subject: [PATCH 016/118] drbd: Add read_requests tree

We do not do collision detection for read requests, but we still need to
look up the request objects when we receive a package over the network.
Using the same data structure for read and write requests results in
simpler code once the tl_hash and app_reads_hash tables are removed.

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0583713..46a4332 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1019,7 +1019,8 @@ struct drbd_conf {
        struct hlist_head *tl_hash;
        unsigned int tl_hash_s;
 
-       /* Interval tree of pending local write requests */
+       /* Interval tree of pending local requests */
+       struct rb_root read_requests;
        struct rb_root write_requests;
 
        /* blocks to resync in this run [unit BM_BLOCK_SIZE] */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 4d85838..c0ea5ba 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3473,6 +3473,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
        /* no need to lock access, we are still initializing this minor device. */
        if (!tl_init(mdev))
                goto out_no_tl;
+       mdev->read_requests = RB_ROOT;
        mdev->write_requests = RB_ROOT;
 
        mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 593576f..d2a78c4 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -260,10 +260,15 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
 
                /* remove the request from the conflict detection
                 * respective block_id verification hash */
-               if (!hlist_unhashed(&req->collision)) {
+               if (!drbd_interval_empty(&req->i)) {
+                       struct rb_root *root;
+
                        hlist_del(&req->collision);
-                       if (!drbd_interval_empty(&req->i))
-                               drbd_remove_interval(&mdev->write_requests, &req->i);
+                       if (rw == WRITE)
+                               root = &mdev->write_requests;
+                       else
+                               root = &mdev->read_requests;
+                       drbd_remove_interval(root, &req->i);
                } else
                        D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
@@ -332,6 +337,7 @@ static int _req_conflicts(struct drbd_request *req)
        struct hlist_head *slot;
 
        D_ASSERT(hlist_unhashed(&req->collision));
+       D_ASSERT(drbd_interval_empty(&req->i));
 
        if (!get_net_conf(mdev))
                return 0;
@@ -493,6 +499,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
                /* so we can verify the handle in the answer packet
                 * corresponding hlist_del is in _req_may_be_done() */
                hlist_add_head(&req->collision, ar_hash_slot(mdev, req->i.sector));
+               drbd_insert_interval(&mdev->read_requests, &req->i);
 
                set_bit(UNPLUG_REMOTE, &mdev->flags);
 
-- 
1.7.4.1

-- 
: 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 related	[flat|nested] 132+ messages in thread

* Re: [Drbd-dev] [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections
  2011-08-25 18:16   ` Joe Perches
@ 2011-08-29 11:42     ` Philipp Reisner
  0 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 11:42 UTC (permalink / raw)
  To: Joe Perches, Jens Axboe, linux-kernel; +Cc: drbd-dev

Am Donnerstag, 25. August 2011, 20:16:25 schrieb Joe Perches:
> On Thu, 2011-08-25 at 17:08 +0200, Philipp Reisner wrote:
> > 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 |   16 +++++++++++++++-
> >  2 files changed, 24 insertions(+), 1 deletions(-)
> 
> Couple of issues with this patch.
> 
> > diff --git a/drivers/block/drbd/drbd_int.h
> > b/drivers/block/drbd/drbd_int.h
> 
> []
> 
> > @@ -102,6 +102,15 @@ struct drbd_tconn;
> 
> []
> 
> > +extern void conn_printk(const char *level, struct drbd_tconn *tconn,
> > const char *fmt, ...);
> 
> This should be
> 
> extern __attribute__((format (printf, 3, 4)))
> void conn_printk(const char *level, struct drbd_tconn *tconn, const char 
> *fmt, ...);
> 
> to have gcc validate the printf format and arguments.
> 
> > diff --git a/drivers/block/drbd/drbd_main.c
> > b/drivers/block/drbd/drbd_main.c
> 
> []
> 
> > @@ -170,6 +170,18 @@ int _get_ldev_if_state(struct drbd_conf *mdev, enum
> > drbd_disk_state mins)
> > 
> >  #endif
> > 
> > +/* printk functions for connections
> > + */
> > +void conn_printk(const char *level, struct drbd_tconn *tconn, const char
> > *fmt, ...) +{
> > +	va_list args;
> > +
> > +	printk("%sd-con %s: ", level, tconn->name);
> > +	va_start(args, fmt);
> > +	vprintk(fmt, args);
> > +	va_end(args);
> 
> And using printk then vprintk is susceptible
> to another thread interleaving a different
> message between the printk and the vprintk.
> 
> Using struct va_format and %pV is better
> because no message interleaving is possible.
> 
[...]

Actually we came across the interleaving issue as
well and solved it at a later point in time by
converting it into a macro. I folded that into this
patch, which gives us:


>From 3fd752956c255f85429f29603fd080e41ca2d90c Mon Sep 17 00:00:00 2001
From: Philipp Reisner <philipp.reisner@linbit.com>
Date: Mon, 7 Feb 2011 14:01:51 +0100
Subject: [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections

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

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 927bf77..4d3320d 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -102,6 +102,16 @@ struct drbd_tconn;
 /* to shorten dev_warn(DEV, "msg"); and relatives statements */
 #define DEV (disk_to_dev(mdev->vdisk))
 
+#define conn_printk(LEVEL, TCONN, FMT, ARGS...) \
+       printk(LEVEL "d-con %s: " FMT, TCONN->name , ## ARGS)
+#define conn_alert(TCONN, FMT, ARGS...)  conn_printk(KERN_ALERT, TCONN, FMT, ## ARGS)
+#define conn_crit(TCONN, FMT, ARGS...)   conn_printk(KERN_CRIT, TCONN, FMT, ## ARGS)
+#define conn_err(TCONN, FMT, ARGS...)    conn_printk(KERN_ERR, TCONN, FMT, ## ARGS)
+#define conn_warn(TCONN, FMT, ARGS...)   conn_printk(KERN_WARNING, TCONN, FMT, ## ARGS)
+#define conn_notice(TCONN, FMT, ARGS...) conn_printk(KERN_NOTICE, TCONN, FMT, ## ARGS)
+#define conn_info(TCONN, FMT, ARGS...)   conn_printk(KERN_INFO, TCONN, FMT, ## ARGS)
+#define conn_dbg(TCONN, FMT, ARGS...)    conn_printk(KERN_DEBUG, TCONN, FMT, ## ARGS)
+
 #define D_ASSERT(exp)  if (!(exp)) \
         dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__)
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index dbd6d72..59a3166 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2217,12 +2217,14 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
        struct drbd_conf *mdev;
        struct gendisk *disk;
        struct request_queue *q;
+       char conn_name[9]; /* drbd1234N */
 
        /* GFP_KERNEL, we are outside of all write-out paths */
        mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
        if (!mdev)
                return NULL;
-       mdev->tconn = drbd_new_tconn("dummy");
+       sprintf(conn_name, "drbd%d", minor);
+       mdev->tconn = drbd_new_tconn(conn_name);
        if (!mdev->tconn)
                goto out_no_tconn;
 
-- 
1.7.4.1

-- 
: 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 related	[flat|nested] 132+ messages in thread

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
       [not found] ` <CAGpXXZKem-uEdF4SyUgpQFV6=d5Vo3v9p3wmcaygAKa4w4x01w@mail.gmail.com>
  2011-08-26 13:54   ` [Drbd-dev] " Lars Ellenberg
@ 2011-08-29 11:46   ` Philipp Reisner
  2011-08-29 13:26     ` Greg Freemyer
  1 sibling, 1 reply; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 11:46 UTC (permalink / raw)
  To: Greg Freemyer, Jens Axboe, linux-kernel; +Cc: drbd-dev

Am Freitag, 26. August 2011, 15:20:51 schrieb Greg Freemyer:
> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
> 
> philipp.reisner@linbit.com> wrote:
> > This the first request for review of drbd-8.4. The complete set has
> > 500 patches. In this first series there are only 118 of these.
> 
> Lars,
> 
> I've only taken a quick glance, but is drbd functional between applying
> each patch?
> 
> It doesn't look like it to me, but I didn't look that close.  I also saw at
> least one patch that introduced a new function with no caller to test it.
> 
> The idea is that a patch series leave a testable / functional kernel after
> each patch in the series is applied sequentially.
> 
> That is the only way git bisect can do its job.
> 
> ie. Introducing a new function but no new caller makes a change, but there
> is no way to test it.  Therefore there is no real value in not merging that
> patch with one that has the new call in it.
> 

Greg,

You replied to mail 000. Please point out to which patch/function you
refer, so that we can fix this.

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] 132+ messages in thread

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-26 15:18     ` Kyle Moffett
@ 2011-08-29 11:51       ` Philipp Reisner
  2011-08-29 12:52         ` Pekka Enberg
  0 siblings, 1 reply; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 11:51 UTC (permalink / raw)
  To: Kyle Moffett, Jens Axboe, linux-kernel; +Cc: drbd-dev, Greg Freemyer

Am Freitag, 26. August 2011, 17:18:53 schrieb Kyle Moffett:
> On Fri, Aug 26, 2011 at 09:54, Lars Ellenberg <lars.ellenberg@linbit.com> 
wrote:
> > On Fri, Aug 26, 2011 at 09:20:51AM -0400, Greg Freemyer wrote:
> >> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
> >> 
> >> philipp.reisner@linbit.com> wrote:
> >> > This the first request for review of drbd-8.4. The complete set has
> >> > 500 patches. In this first series there are only 118 of these.
> >> 
> >> I've only taken a quick glance, but is drbd functional between applying
> >> each patch?
> >> 
> >> It doesn't look like it to me, but I didn't look that close.  I also saw
> >> at least one patch that introduced a new function with no caller to
> >> test it.
> >> 
> >> The idea is that a patch series leave a testable / functional kernel
> >> after each patch in the series is applied sequentially.
> >> 
> >> That is the only way git bisect can do its job.
> > 
> > Very likely DRBD will not always be completely functional between
> > any arbitrary two of these patches.
> > 
> > The kernel as such will still be bisectable "just fine".
> 
> No.
> 
> That's not the way that kernel development works.
> 
> Besides which, that's not the way that "git bisect" works.
> 
> For example, say I have a driver bug that happens to be triggering
> on my server which also happens to use GFS on DRBD.  I try to
> bisect the bug and it happens to pick a commit right in the middle
> of this DRBD branch.
> 
> Suddenly DRBD is unusable or corrupting data or something, which
> is unacceptable for an unrelated bisection of a driver bug.
> 

No. It compiles after each and every patch. Verified. It is
functional after each and every patch, though providing the
feature set that was present before this whole patch series.

If you are looking for a regression with "git bisect" then
you are using DRBD with only the old features.

The new feature set, might be partially broken, but introducing
the new features is the whole point of this patch series.

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] 132+ messages in thread

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-29 11:51       ` Philipp Reisner
@ 2011-08-29 12:52         ` Pekka Enberg
  2011-08-29 15:38           ` Philipp Reisner
  0 siblings, 1 reply; 132+ messages in thread
From: Pekka Enberg @ 2011-08-29 12:52 UTC (permalink / raw)
  To: Philipp Reisner
  Cc: Kyle Moffett, Jens Axboe, linux-kernel, drbd-dev, Greg Freemyer

On Mon, Aug 29, 2011 at 2:51 PM, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> The new feature set, might be partially broken, but introducing
> the new features is the whole point of this patch series.

If that new feature can, for example, corrupt your data while you're
doing "git bisect" on non-DRBD regression, that's no good. Can that
happen?

                        Pekka

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

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-29 11:46   ` Philipp Reisner
@ 2011-08-29 13:26     ` Greg Freemyer
  2011-08-29 16:07       ` Philipp Reisner
  0 siblings, 1 reply; 132+ messages in thread
From: Greg Freemyer @ 2011-08-29 13:26 UTC (permalink / raw)
  To: Philipp Reisner; +Cc: Jens Axboe, linux-kernel, drbd-dev

On Mon, Aug 29, 2011 at 7:46 AM, Philipp Reisner
<philipp.reisner@linbit.com> wrote:
> Am Freitag, 26. August 2011, 15:20:51 schrieb Greg Freemyer:
>> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
>>
>> philipp.reisner@linbit.com> wrote:
>> > This the first request for review of drbd-8.4. The complete set has
>> > 500 patches. In this first series there are only 118 of these.
>>
>> Lars,
>>
>> I've only taken a quick glance, but is drbd functional between applying
>> each patch?
>>
>> It doesn't look like it to me, but I didn't look that close.  I also saw at
>> least one patch that introduced a new function with no caller to test it.
>>
>> The idea is that a patch series leave a testable / functional kernel after
>> each patch in the series is applied sequentially.
>>
>> That is the only way git bisect can do its job.
>>
>> ie. Introducing a new function but no new caller makes a change, but there
>> is no way to test it.  Therefore there is no real value in not merging that
>> patch with one that has the new call in it.
>>
>
> Greg,
>
> You replied to mail 000. Please point out to which patch/function you
> refer, so that we can fix this.
>
> Best,
>  Phil

Phillip,

Take a look at patch 115 of 118 in your series.  I did not review the
whole series, I just poked around briefly and noticed this one.

Greg

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

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-29 12:52         ` Pekka Enberg
@ 2011-08-29 15:38           ` Philipp Reisner
  0 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 15:38 UTC (permalink / raw)
  To: Pekka Enberg, Jens Axboe, linux-kernel
  Cc: Kyle Moffett, drbd-dev, Greg Freemyer

Am Montag, 29. August 2011, 14:52:56 schrieb Pekka Enberg:
> On Mon, Aug 29, 2011 at 2:51 PM, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > The new feature set, might be partially broken, but introducing
> > the new features is the whole point of this patch series.
> 
> If that new feature can, for example, corrupt your data while you're
> doing "git bisect" on non-DRBD regression, that's no good. Can that
> happen?
> 

No, that can not happen. Maybe it fails to connect to the peer, etc...
It will not destroy data.

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] 132+ messages in thread

* Re: [Drbd-dev] [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd
  2011-08-29 13:26     ` Greg Freemyer
@ 2011-08-29 16:07       ` Philipp Reisner
  0 siblings, 0 replies; 132+ messages in thread
From: Philipp Reisner @ 2011-08-29 16:07 UTC (permalink / raw)
  To: Greg Freemyer, Jens Axboe, linux-kernel; +Cc: drbd-dev

Am Montag, 29. August 2011, 15:26:16 schrieb Greg Freemyer:
> On Mon, Aug 29, 2011 at 7:46 AM, Philipp Reisner
> 
> <philipp.reisner@linbit.com> wrote:
> > Am Freitag, 26. August 2011, 15:20:51 schrieb Greg Freemyer:
> >> On Thu, Aug 25, 2011 at 11:06 AM, Philipp Reisner <
> >> 
> >> philipp.reisner@linbit.com> wrote:
> >> > This the first request for review of drbd-8.4. The complete set has
> >> > 500 patches. In this first series there are only 118 of these.
> >> 
> >> Lars,
> >> 
> >> I've only taken a quick glance, but is drbd functional between applying
> >> each patch?
> >> 
> >> It doesn't look like it to me, but I didn't look that close.  I also saw
> >> at least one patch that introduced a new function with no caller to
> >> test it.
> >> 
> >> The idea is that a patch series leave a testable / functional kernel
> >> after each patch in the series is applied sequentially.
> >> 
> >> That is the only way git bisect can do its job.
> >> 
> >> ie. Introducing a new function but no new caller makes a change, but
> >> there is no way to test it.  Therefore there is no real value in not
> >> merging that patch with one that has the new call in it.
> > 
> > Greg,
> > 
> > You replied to mail 000. Please point out to which patch/function you
> > refer, so that we can fix this.
> > 
> > Best,
> >  Phil
> 
> Phillip,
> 
> Take a look at patch 115 of 118 in your series.  I did not review the
> whole series, I just poked around briefly and noticed this one.
> 
> Greg

Ok, I merged 115 into 117, that gives a new 116:

>From dbe9017ffee428c11cbbf4243fbcf9ed633d7b82 Mon Sep 17 00:00:00 2001
From: Philipp Reisner <philipp.reisner@linbit.com>
Date: Tue, 15 Feb 2011 11:09:33 +0100
Subject: [PATCH 116/117] drbd: implemented receiving of P_CONN_ST_CHG_REQ

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     |   10 ++++++++++
 drivers/block/drbd/drbd_receiver.c |   10 ++++++++--
 drivers/block/drbd/drbd_state.h    |    1 +
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 0cf5196..26ea665 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1219,6 +1219,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 int _drbd_send_bitmap(struct drbd_conf *mdev);
 extern int 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 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);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index d8fd6dd..910dff7 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -990,6 +990,16 @@ int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv 
retcode)
        return drbd_send_cmd(mdev, USE_META_SOCKET, P_STATE_CHG_REPLY, &p.head, sizeof(p));
 }
 
+int conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
+{
+       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, USE_META_SOCKET, cmd, &p.head, sizeof(p));
+}
+
 int fill_bitmap_rle_bits(struct drbd_conf *mdev,
        struct p_compressed_bm *p,
        struct bm_xfer_ctx *c)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bdd3f00..e346245 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3235,9 +3235,14 @@ static int receive_req_state(struct drbd_conf *mdev, enum 
drbd_packet cmd,
        mask = convert_state(mask);
        val = convert_state(val);
 
-       rv = drbd_change_state(mdev, CS_VERBOSE, mask, val);
+       if (cmd == P_CONN_ST_CHG_REQ) {
+               rv = conn_request_state(mdev->tconn, mask, val, CS_VERBOSE | 
CS_LOCAL_ONLY);
+               conn_send_sr_reply(mdev->tconn, rv);
+       } else {
+               rv = drbd_change_state(mdev, CS_VERBOSE, mask, val);
+               drbd_send_sr_reply(mdev, rv);
+       }
 
-       drbd_send_sr_reply(mdev, rv);
        drbd_md_sync(mdev);
 
        return true;
@@ -3771,6 +3776,7 @@ static struct data_cmd drbd_cmd_handler[] = {
        [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest },
        [P_DELAY_PROBE]     = { 0, sizeof(struct p_delay_probe93), receive_skip },
        [P_OUT_OF_SYNC]     = { 0, sizeof(struct p_block_desc), receive_out_of_sync },
+       [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_state },
        /* anything missing from this table is in
         * the asender_tbl, see get_asender_cmd */
        [P_MAX_CMD]         = { 0, 0, NULL },
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index d312d84..5fdbdf0 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -63,6 +63,7 @@ enum chg_state_flags {
        CS_SERIALIZE    = 8,
        CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
        CS_NO_CSTATE_CHG = 16, /* Do not display changes in cstate. Internal to 
drbd_state.c */
+       CS_LOCAL_ONLY = 32, /* Do not consider a device pair wide state change */
 };
 
 extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,
-- 
1.7.4.1

-- 
: 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 related	[flat|nested] 132+ messages in thread

end of thread, other threads:[~2011-08-29 16:07 UTC | newest]

Thread overview: 132+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-25 15:06 [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd Philipp Reisner
2011-08-25 15:06 ` [PATCH 001/118] drbd: Get rid of req_validator_fn typedef Philipp Reisner
2011-08-25 15:06 ` [PATCH 002/118] drbd: Remove superfluous declaration Philipp Reisner
2011-08-25 15:06 ` [PATCH 003/118] drbd: Consistently use block_id == ID_SYNCER for checksum based resync and online verify Philipp Reisner
2011-08-25 15:07 ` [PATCH 004/118] drbd: Get rid of BE_DRBD_MAGIC and BE_DRBD_MAGIC_BIG Philipp Reisner
2011-08-25 15:07 ` [PATCH 005/118] drbd: Endianness convert the constants instead of the variables Philipp Reisner
2011-08-25 15:07 ` [PATCH 006/118] drbd: Magic reserved block_id value cleanup Philipp Reisner
2011-08-25 15:07 ` [PATCH 007/118] drbd: Move drbd_free_tl_hash() to drbd_main() Philipp Reisner
2011-08-25 15:07 ` [PATCH 008/118] drbd: Update outdated comment Philipp Reisner
2011-08-25 15:07 ` [PATCH 009/118] drbd: Request lookup code cleanup (1) Philipp Reisner
2011-08-25 15:07 ` [PATCH 010/118] drbd: Request lookup code cleanup (2) Philipp Reisner
2011-08-25 15:07 ` [PATCH 011/118] drbd: Request lookup code cleanup (3) Philipp Reisner
2011-08-25 15:07 ` [PATCH 012/118] drbd: Request lookup code cleanup (4) Philipp Reisner
2011-08-25 15:07 ` [PATCH 013/118] drbd: Add interval tree data structure Philipp Reisner
2011-08-25 15:07 ` [PATCH 014/118] drbd: Put sector and size in struct drbd_request into struct drbd_interval Philipp Reisner
2011-08-25 15:07 ` [PATCH 015/118] drbd: Use interval tree for overlapping write request detection Philipp Reisner
2011-08-25 15:07 ` [PATCH 016/118] drbd: Add read_requests tree Philipp Reisner
2011-08-25 18:02   ` [Drbd-dev] " Pawel Jakub Dawidek
2011-08-29 11:42     ` Philipp Reisner
2011-08-25 15:07 ` [PATCH 017/118] drbd: Use the read and write request trees for request lookups Philipp Reisner
2011-08-25 15:07 ` [PATCH 018/118] drbd: Put sector and size in struct drbd_epoch_entry into struct drbd_interval Philipp Reisner
2011-08-25 15:07 ` [PATCH 019/118] drbd: Use interval tree for overlapping epoch entry detection Philipp Reisner
2011-08-25 15:07 ` [PATCH 020/118] drbd: Remove the unused hash tables Philipp Reisner
2011-08-25 15:07 ` [PATCH 021/118] drbd: Convert all constants in enum drbd_req_event to upper case Philipp Reisner
2011-08-25 15:07 ` [PATCH 022/118] drbd: Convert all constants in enum drbd_thread_state " Philipp Reisner
2011-08-25 15:07 ` [PATCH 023/118] drbd: Replace the ERR_IF macro with an assert-like macro Philipp Reisner
2011-08-25 15:07 ` [PATCH 024/118] drbd: Remove some useless paranoia code Philipp Reisner
2011-08-25 15:07 ` [PATCH 025/118] drbd: Inline function overlaps() is now unused Philipp Reisner
2011-08-25 15:07 ` [PATCH 026/118] drbd: Interval tree bugfix Philipp Reisner
2011-08-25 15:07 ` [PATCH 027/118] idr: idr_for_each_entry() macro Philipp Reisner
2011-08-25 15:07 ` [PATCH 028/118] drbd: Minimal struct drbd_tconn Philipp Reisner
2011-08-25 15:07 ` [PATCH 029/118] drbd: moved net_conf from mdev to tconn Philipp Reisner
2011-08-25 15:07 ` [PATCH 030/118] drbd: moved net_cont and net_cnt_wait " Philipp Reisner
2011-08-25 15:07 ` [PATCH 031/118] drbd: moved data and meta " Philipp Reisner
2011-08-25 15:07 ` [PATCH 032/118] drbd: moved receiver, worker and asender " Philipp Reisner
2011-08-25 15:07 ` [PATCH 033/118] drbd: moved agreed_pro_version, last_received and ko_count " Philipp Reisner
2011-08-25 15:07 ` [PATCH 034/118] drbd: moved req_lock and transfer log from mdev " Philipp Reisner
2011-08-25 15:07 ` [PATCH 035/118] drbd: moved crypto transformations and friends " Philipp Reisner
2011-08-25 15:07 ` [PATCH 036/118] drbd: Made drbd_flush_workqueue() to take a tconn instead of an mdev Philipp Reisner
2011-08-25 15:07 ` [PATCH 037/118] drbd: Preparing to use p_header96 for all packets Philipp Reisner
2011-08-25 15:07 ` [PATCH 038/118] drbd: Replaced all p_header80 with a generic p_header Philipp Reisner
2011-08-25 15:07 ` [PATCH 039/118] drbd: Use new header layout, and send volume IOs Philipp Reisner
2011-08-25 15:07 ` [PATCH 040/118] drbd: Implemented receiving of new style packets on meta socket Philipp Reisner
2011-08-25 15:07 ` [PATCH 041/118] drbd: Do not access tconn after it was freed Philipp Reisner
2011-08-25 15:07 ` [PATCH 042/118] drbd: Move cmdname() out of drbd_int.h Philipp Reisner
2011-08-25 15:07 ` [PATCH 043/118] drbd: Rename "enum drbd_packets" to "enum drbd_packet" Philipp Reisner
2011-08-25 15:07 ` [PATCH 044/118] drbd: Remove redundant initialization Philipp Reisner
2011-08-25 15:07 ` [PATCH 045/118] drbd: Initialize the sequence number sent over the network even when not used Philipp Reisner
2011-08-25 15:07 ` [PATCH 046/118] drbd: Move sequence number logic into drbd_receiver.c and simplify it Philipp Reisner
2011-08-25 15:07 ` [PATCH 047/118] drbd: Move some functions to where they are used Philipp Reisner
2011-08-25 15:07 ` [PATCH 048/118] drbd: struct drbd_request: Introduce a new collision flag Philipp Reisner
2011-08-25 15:07 ` [PATCH 049/118] drbd: Remove redundant check from drbd_contains_interval() Philipp Reisner
2011-08-25 15:07 ` [PATCH 050/118] drbd: Allow to wait for the completion of an epoch entry as well Philipp Reisner
2011-08-25 15:07 ` [PATCH 051/118] drbd: _req_conflicts(): Get rid of the epoch_entries tree Philipp Reisner
2011-08-25 15:07 ` [PATCH 052/118] drbd: Remove unnecessary reference counting left-over Philipp Reisner
2011-08-25 15:07 ` [PATCH 053/118] drbd: Defer new writes when detecting conflicting writes Philipp Reisner
2011-08-25 15:07 ` [PATCH 054/118] drbd: Make the peer_seq updating code more obvious Philipp Reisner
2011-08-25 15:07 ` [PATCH 055/118] drbd: Improve the drbd_find_overlap() documentation Philipp Reisner
2011-08-25 15:07 ` [PATCH 056/118] drbd: Remove unused variable in struct drbd_conf Philipp Reisner
2011-08-25 15:07 ` [PATCH 057/118] drbd: Rename struct drbd_epoch_entry to struct drbd_peer_request Philipp Reisner
2011-08-25 15:07 ` [PATCH 058/118] drbd: Clean up some left-overs Philipp Reisner
2011-08-25 15:07 ` [PATCH 059/118] drbd: Update some comments Philipp Reisner
2011-08-25 15:07 ` [PATCH 060/118] drbd: Local variable renames: e -> peer_req Philipp Reisner
2011-08-25 15:07 ` [PATCH 061/118] drbd: Moved the state functions into its own source file Philipp Reisner
2011-08-25 15:07 ` [PATCH 062/118] drbd: Moved the thread name into the data structure Philipp Reisner
2011-08-25 15:07 ` [PATCH 063/118] drbd: Eliminated the user of drbd_task_to_thread() Philipp Reisner
2011-08-25 15:08 ` [PATCH 064/118] drbd: Moved code Philipp Reisner
2011-08-25 15:08 ` [PATCH 065/118] drbd: Do no sleep long in drbd_start_resync Philipp Reisner
2011-08-25 15:08 ` [PATCH 066/118] drbd: Revert "Make sure we dont send state if a cluster wide state change is in progress" Philipp Reisner
2011-08-25 15:08 ` [PATCH 067/118] drbd: Moving state related macros to drbd_state.h Philipp Reisner
2011-08-25 15:08 ` [PATCH 068/118] drbd: conn_printk() a dev_printk() alike for drbd's connections Philipp Reisner
2011-08-25 18:16   ` Joe Perches
2011-08-29 11:42     ` [Drbd-dev] " Philipp Reisner
2011-08-25 15:08 ` [PATCH 069/118] drbd: Converted drbd_try_connect() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 070/118] drbd: Converted drbd_wait_for_connect() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 071/118] drbd: Started to separated connection flags (tconn) from block device flags (mdev) Philipp Reisner
2011-08-25 15:08 ` [PATCH 072/118] drbd: Moved DISCARD_CONCURRENT to the per connection (tconn) flags Philipp Reisner
2011-08-25 15:08 ` [PATCH 073/118] drbd: Moved SEND_PING " Philipp Reisner
2011-08-25 15:08 ` [PATCH 074/118] drbd: Moved SIGNAL_ASENDER " Philipp Reisner
2011-08-25 15:08 ` [PATCH 075/118] drbd: Converted wake_asender() and request_ping() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 076/118] drbd: Converted helper functions for drbd_send() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 077/118] drbd: Converted drbd_send() from mdev " Philipp Reisner
2011-08-25 15:08 ` [PATCH 078/118] drbd: Converted drbd_send_fp() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 079/118] drbd: Removed unused mdev argument from drbd_recv_short() and drbd_socket_okay() Philipp Reisner
2011-08-25 15:08 ` [PATCH 080/118] drbd: Converted drbd_recv_fp() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 081/118] drbd: Converted drbd_send_handshake() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 082/118] drbd: Converted drbd_recv() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 083/118] drbd: struct packet_info to hold information of decoded packets Philipp Reisner
2011-08-25 15:08 ` [PATCH 084/118] drbd: Converted decode_header() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 085/118] drbd: Converted drbd_recv_header() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 086/118] drbd: Converted drbd_do_handshake() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 087/118] drbd: Converted drbd_(get|put)_data_sock() and drbd_send_cmd2() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 088/118] drbd: Converted drbd_do_auth() from mdev " Philipp Reisner
2011-08-25 15:08 ` [PATCH 089/118] drbd: Converted drbd_send_protocol() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 090/118] drbd: Use and idr data structure to map volume numbers to mdev pointers Philipp Reisner
2011-08-25 15:08 ` [PATCH 091/118] drbd: Converted drbd_connect() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 092/118] drbd: Converted drbd_calc_cpu_mask() and drbd_thread_current_set_cpu() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 093/118] drbd: Converted drbdd() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 094/118] drbd: Converted drbd_free_sock() and drbd_disconnect() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 095/118] drbd: Moved the mdev member into drbd_work (from drbd_request and drbd_peer_request) Philipp Reisner
2011-08-25 15:08 ` [PATCH 096/118] drbd: Consolidated the setup of the thread name into the framework Philipp Reisner
2011-08-25 15:08 ` [PATCH 097/118] drbd: Converted drbdd_init() from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 098/118] drbd: Converted drbd_asender() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 099/118] drbd: Converted drbd_worker() " Philipp Reisner
2011-08-25 15:08 ` [PATCH 100/118] drbd: drbd_thread has now a pointer to a tconn instead of to a mdev Philipp Reisner
2011-08-25 15:08 ` [PATCH 101/118] drbd: Moved some initializing code into drbd_new_tconn() Philipp Reisner
2011-08-25 15:08 ` [PATCH 102/118] drbd: Generalized the work callbacks Philipp Reisner
2011-08-25 15:08 ` [PATCH 103/118] drbd: Converted drbd_send_ping() and related functions from mdev to tconn Philipp Reisner
2011-08-25 15:08 ` [PATCH 104/118] drbd: Extracted after_conn_state_ch() out of after_state_ch() Philipp Reisner
2011-08-25 15:08 ` [PATCH 105/118] drbd: Renamed is_valid_state_transition() to is_valid_soft_transition() Philipp Reisner
2011-08-25 15:08 ` [PATCH 106/118] drbd: Extracted is_valid_transition() out of sanitize_state() Philipp Reisner
2011-08-25 15:08 ` [PATCH 107/118] drbd: Extracted is_valid_conn_transition() out of is_valid_transition() Philipp Reisner
2011-08-25 15:08 ` [PATCH 108/118] drbd: Removed the os parameter form sanitize_state() Philipp Reisner
2011-08-25 15:08 ` [PATCH 109/118] drbd: Code de-duplication; new function apply_mask_val() Philipp Reisner
2011-08-25 15:08 ` [PATCH 110/118] drbd: Killed volume0; last step of multi-volume-enablement Philipp Reisner
2011-08-25 15:08 ` [PATCH 111/118] drbd: Removed drbd_state_lock() and drbd_state_unlock() Philipp Reisner
2011-08-25 15:08 ` [PATCH 112/118] drbd: Introduced tconn->cstate_mutex Philipp Reisner
2011-08-25 15:08 ` [PATCH 113/118] drbd: Implemented conn_send_state_req() Philipp Reisner
2011-08-25 15:08 ` [PATCH 114/118] drbd: Global_state_lock not necessary here Philipp Reisner
2011-08-25 15:08 ` [PATCH 115/118] drbd: Implemented conn_send_sr_reply() Philipp Reisner
2011-08-25 15:08 ` [PATCH 116/118] drbd: Implemented receiving of P_CONN_ST_CHG_REPLY Philipp Reisner
2011-08-25 15:08 ` [PATCH 117/118] drbd: implemented receiving of P_CONN_ST_CHG_REQ Philipp Reisner
2011-08-25 15:08 ` [PATCH 118/118] drbd: Implemented connection wide state changes Philipp Reisner
2011-08-26  1:30 ` [RFC 000/118] drbd: part 1 of adding multiple volume support to drbd David Miller
     [not found] ` <CAGpXXZKem-uEdF4SyUgpQFV6=d5Vo3v9p3wmcaygAKa4w4x01w@mail.gmail.com>
2011-08-26 13:54   ` [Drbd-dev] " Lars Ellenberg
2011-08-26 15:18     ` Kyle Moffett
2011-08-29 11:51       ` Philipp Reisner
2011-08-29 12:52         ` Pekka Enberg
2011-08-29 15:38           ` Philipp Reisner
2011-08-29 11:46   ` Philipp Reisner
2011-08-29 13:26     ` Greg Freemyer
2011-08-29 16:07       ` Philipp Reisner

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.