drbd: Introduce "peer_device" object between "device" and "connection"

In a setup where a device (aka volume) can replicate to multiple peers and one
connection can be shared between multiple devices, we need separate objects to
represent devices on peer nodes and network connections.

As a first step to introduce multiple connections per device, give each
drbd_device object a single drbd_peer_device object which connects it to a
drbd_connection object.

Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e4fd180..b7c858f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -308,7 +308,7 @@
  */
 void tl_abort_disk_io(struct drbd_device *device)
 {
-	struct drbd_connection *connection = device->connection;
+	struct drbd_connection *connection = first_peer_device(device)->connection;
 	struct drbd_request *req, *r;
 
 	spin_lock_irq(&connection->req_lock);
@@ -633,7 +633,7 @@
 
 void *drbd_prepare_command(struct drbd_device *device, struct drbd_socket *sock)
 {
-	return conn_prepare_command(device->connection, sock);
+	return conn_prepare_command(first_peer_device(device)->connection, sock);
 }
 
 static int __send_command(struct drbd_connection *connection, int vnr,
@@ -686,7 +686,7 @@
 {
 	int err;
 
-	err = __send_command(device->connection, device->vnr, sock, cmd, header_size,
+	err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, header_size,
 			     data, size);
 	mutex_unlock(&sock->mutex);
 	return err;
@@ -717,18 +717,18 @@
 	struct drbd_socket *sock;
 	struct p_rs_param_95 *p;
 	int size;
-	const int apv = device->connection->agreed_pro_version;
+	const int apv = first_peer_device(device)->connection->agreed_pro_version;
 	enum drbd_packet cmd;
 	struct net_conf *nc;
 	struct disk_conf *dc;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
 
 	rcu_read_lock();
-	nc = rcu_dereference(device->connection->net_conf);
+	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
 
 	size = apv <= 87 ? sizeof(struct p_rs_param)
 		: apv == 88 ? sizeof(struct p_rs_param)
@@ -831,7 +831,7 @@
 	if (!get_ldev_if_state(device, D_NEGOTIATING))
 		return 0;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p) {
 		put_ldev(device);
@@ -845,7 +845,7 @@
 	device->comm_bm_set = drbd_bm_total_weight(device);
 	p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set);
 	rcu_read_lock();
-	uuid_flags |= rcu_dereference(device->connection->net_conf)->discard_my_data ? 1 : 0;
+	uuid_flags |= rcu_dereference(first_peer_device(device)->connection->net_conf)->discard_my_data ? 1 : 0;
 	rcu_read_unlock();
 	uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0;
 	uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
@@ -900,7 +900,7 @@
 	drbd_print_uuids(device, "updated sync UUID");
 	drbd_md_sync(device);
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (p) {
 		p->uuid = cpu_to_be64(uuid);
@@ -933,14 +933,14 @@
 		max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
 	}
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
 
-	if (device->connection->agreed_pro_version <= 94)
+	if (first_peer_device(device)->connection->agreed_pro_version <= 94)
 		max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
-	else if (device->connection->agreed_pro_version < 100)
+	else if (first_peer_device(device)->connection->agreed_pro_version < 100)
 		max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95);
 
 	p->d_size = cpu_to_be64(d_size);
@@ -961,7 +961,7 @@
 	struct drbd_socket *sock;
 	struct p_state *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -984,7 +984,7 @@
 	struct drbd_socket *sock;
 	struct p_state *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -997,7 +997,7 @@
 	struct drbd_socket *sock;
 	struct p_req_state *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1027,7 +1027,7 @@
 	struct drbd_socket *sock;
 	struct p_req_state_reply *p;
 
-	sock = &device->connection->meta;
+	sock = &first_peer_device(device)->connection->meta;
 	p = drbd_prepare_command(device, sock);
 	if (p) {
 		p->retcode = cpu_to_be32(retcode);
@@ -1081,9 +1081,9 @@
 
 	/* may we use this feature? */
 	rcu_read_lock();
-	use_rle = rcu_dereference(device->connection->net_conf)->use_rle;
+	use_rle = rcu_dereference(first_peer_device(device)->connection->net_conf)->use_rle;
 	rcu_read_unlock();
-	if (!use_rle || device->connection->agreed_pro_version < 90)
+	if (!use_rle || first_peer_device(device)->connection->agreed_pro_version < 90)
 		return 0;
 
 	if (c->bit_offset >= c->bm_bits)
@@ -1172,8 +1172,8 @@
 static int
 send_bitmap_rle_or_plain(struct drbd_device *device, struct bm_xfer_ctx *c)
 {
-	struct drbd_socket *sock = &device->connection->data;
-	unsigned int header_size = drbd_header_size(device->connection);
+	struct drbd_socket *sock = &first_peer_device(device)->connection->data;
+	unsigned int header_size = drbd_header_size(first_peer_device(device)->connection);
 	struct p_compressed_bm *p = sock->sbuf + header_size;
 	int len, err;
 
@@ -1184,7 +1184,7 @@
 
 	if (len) {
 		dcbp_set_code(p, RLE_VLI_Bits);
-		err = __send_command(device->connection, device->vnr, sock,
+		err = __send_command(first_peer_device(device)->connection, device->vnr, sock,
 				     P_COMPRESSED_BITMAP, sizeof(*p) + len,
 				     NULL, 0);
 		c->packets[0]++;
@@ -1205,7 +1205,7 @@
 		len = num_words * sizeof(*p);
 		if (len)
 			drbd_bm_get_lel(device, c->word_offset, num_words, p);
-		err = __send_command(device->connection, device->vnr, sock, P_BITMAP, len, NULL, 0);
+		err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_BITMAP, len, NULL, 0);
 		c->word_offset += num_words;
 		c->bit_offset = c->word_offset * BITS_PER_LONG;
 
@@ -1265,7 +1265,7 @@
 
 int drbd_send_bitmap(struct drbd_device *device)
 {
-	struct drbd_socket *sock = &device->connection->data;
+	struct drbd_socket *sock = &first_peer_device(device)->connection->data;
 	int err = -1;
 
 	mutex_lock(&sock->mutex);
@@ -1309,7 +1309,7 @@
 	if (device->state.conn < C_CONNECTED)
 		return -EIO;
 
-	sock = &device->connection->meta;
+	sock = &first_peer_device(device)->connection->meta;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1326,8 +1326,8 @@
 void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd,
 		      struct p_data *dp, int data_size)
 {
-	if (device->connection->peer_integrity_tfm)
-		data_size -= crypto_hash_digestsize(device->connection->peer_integrity_tfm);
+	if (first_peer_device(device)->connection->peer_integrity_tfm)
+		data_size -= crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
 	_drbd_send_ack(device, cmd, dp->sector, cpu_to_be32(data_size),
 		       dp->block_id);
 }
@@ -1370,7 +1370,7 @@
 	struct drbd_socket *sock;
 	struct p_block_req *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1388,7 +1388,7 @@
 
 	/* FIXME: Put the digest into the preallocated socket buffer.  */
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1404,7 +1404,7 @@
 	struct drbd_socket *sock;
 	struct p_block_req *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1476,9 +1476,9 @@
 	void *addr;
 	int err;
 
-	socket = device->connection->data.socket;
+	socket = first_peer_device(device)->connection->data.socket;
 	addr = kmap(page) + offset;
-	err = drbd_send_all(device->connection, socket, addr, size, msg_flags);
+	err = drbd_send_all(first_peer_device(device)->connection, socket, addr, size, msg_flags);
 	kunmap(page);
 	if (!err)
 		device->send_cnt += size >> 9;
@@ -1488,7 +1488,7 @@
 static int _drbd_send_page(struct drbd_device *device, struct page *page,
 		    int offset, size_t size, unsigned msg_flags)
 {
-	struct socket *socket = device->connection->data.socket;
+	struct socket *socket = first_peer_device(device)->connection->data.socket;
 	mm_segment_t oldfs = get_fs();
 	int len = size;
 	int err = -EIO;
@@ -1503,7 +1503,7 @@
 		return _drbd_no_send_page(device, page, offset, size, msg_flags);
 
 	msg_flags |= MSG_NOSIGNAL;
-	drbd_update_congested(device->connection);
+	drbd_update_congested(first_peer_device(device)->connection);
 	set_fs(KERNEL_DS);
 	do {
 		int sent;
@@ -1511,7 +1511,7 @@
 		sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
 		if (sent <= 0) {
 			if (sent == -EAGAIN) {
-				if (we_should_drop_the_connection(device->connection, socket))
+				if (we_should_drop_the_connection(first_peer_device(device)->connection, socket))
 					break;
 				continue;
 			}
@@ -1525,7 +1525,7 @@
 		offset += sent;
 	} while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
 	set_fs(oldfs);
-	clear_bit(NET_CONGESTED, &device->connection->flags);
+	clear_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags);
 
 	if (len == 0) {
 		err = 0;
@@ -1593,7 +1593,7 @@
 
 static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
 {
-	if (device->connection->agreed_pro_version >= 95)
+	if (first_peer_device(device)->connection->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) |
@@ -1613,9 +1613,10 @@
 	int dgs;
 	int err;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
-	dgs = device->connection->integrity_tfm ? crypto_hash_digestsize(device->connection->integrity_tfm) : 0;
+	dgs = first_peer_device(device)->connection->integrity_tfm ?
+	      crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
 
 	if (!p)
 		return -EIO;
@@ -1626,7 +1627,7 @@
 	if (device->state.conn >= C_SYNC_SOURCE &&
 	    device->state.conn <= C_PAUSED_SYNC_T)
 		dp_flags |= DP_MAY_SET_IN_SYNC;
-	if (device->connection->agreed_pro_version >= 100) {
+	if (first_peer_device(device)->connection->agreed_pro_version >= 100) {
 		if (req->rq_state & RQ_EXP_RECEIVE_ACK)
 			dp_flags |= DP_SEND_RECEIVE_ACK;
 		if (req->rq_state & RQ_EXP_WRITE_ACK)
@@ -1634,8 +1635,8 @@
 	}
 	p->dp_flags = cpu_to_be32(dp_flags);
 	if (dgs)
-		drbd_csum_bio(device, device->connection->integrity_tfm, req->master_bio, p + 1);
-	err = __send_command(device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
+		drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1);
+	err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
 	if (!err) {
 		/* For protocol A, we have to memcpy the payload into
 		 * socket buffers, as we may complete right away
@@ -1658,7 +1659,7 @@
 			/* 64 byte, 512 bit, is the largest digest size
 			 * currently supported in kernel crypto. */
 			unsigned char digest[64];
-			drbd_csum_bio(device, device->connection->integrity_tfm, req->master_bio, digest);
+			drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
 			if (memcmp(p + 1, digest, dgs)) {
 				dev_warn(DEV,
 					"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
@@ -1685,10 +1686,11 @@
 	int err;
 	int dgs;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 
-	dgs = device->connection->integrity_tfm ? crypto_hash_digestsize(device->connection->integrity_tfm) : 0;
+	dgs = first_peer_device(device)->connection->integrity_tfm ?
+	      crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
 
 	if (!p)
 		return -EIO;
@@ -1697,8 +1699,8 @@
 	p->seq_num = 0;  /* unused */
 	p->dp_flags = 0;
 	if (dgs)
-		drbd_csum_ee(device, device->connection->integrity_tfm, peer_req, p + 1);
-	err = __send_command(device->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
+		drbd_csum_ee(device, first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1);
+	err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
 	if (!err)
 		err = _drbd_send_zc_ee(device, peer_req);
 	mutex_unlock(&sock->mutex);  /* locked by drbd_prepare_command() */
@@ -1711,7 +1713,7 @@
 	struct drbd_socket *sock;
 	struct p_block_desc *p;
 
-	sock = &device->connection->data;
+	sock = &first_peer_device(device)->connection->data;
 	p = drbd_prepare_command(device, sock);
 	if (!p)
 		return -EIO;
@@ -1832,7 +1834,7 @@
 	int rv = 0;
 
 	mutex_lock(&drbd_main_mutex);
-	spin_lock_irqsave(&device->connection->req_lock, flags);
+	spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
 	/* to have a stable device->state.role
 	 * and no race with updating open_cnt */
 
@@ -1845,7 +1847,7 @@
 
 	if (!rv)
 		device->open_cnt++;
-	spin_unlock_irqrestore(&device->connection->req_lock, flags);
+	spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
 	mutex_unlock(&drbd_main_mutex);
 
 	return rv;
@@ -1950,9 +1952,9 @@
 void drbd_device_cleanup(struct drbd_device *device)
 {
 	int i;
-	if (device->connection->receiver.t_state != NONE)
+	if (first_peer_device(device)->connection->receiver.t_state != NONE)
 		dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
-				device->connection->receiver.t_state);
+				first_peer_device(device)->connection->receiver.t_state);
 
 	device->al_writ_cnt  =
 	device->bm_writ_cnt  =
@@ -1970,7 +1972,7 @@
 		device->rs_mark_left[i] = 0;
 		device->rs_mark_time[i] = 0;
 	}
-	D_ASSERT(device->connection->net_conf == NULL);
+	D_ASSERT(first_peer_device(device)->connection->net_conf == NULL);
 
 	drbd_set_my_capacity(device, 0);
 	if (device->bitmap) {
@@ -1990,7 +1992,7 @@
 	D_ASSERT(list_empty(&device->read_ee));
 	D_ASSERT(list_empty(&device->net_ee));
 	D_ASSERT(list_empty(&device->resync_reads));
-	D_ASSERT(list_empty(&device->connection->sender_work.q));
+	D_ASSERT(list_empty(&first_peer_device(device)->connection->sender_work.q));
 	D_ASSERT(list_empty(&device->resync_work.list));
 	D_ASSERT(list_empty(&device->unplug_work.list));
 	D_ASSERT(list_empty(&device->go_diskless.list));
@@ -2159,7 +2161,7 @@
 void drbd_minor_destroy(struct kref *kref)
 {
 	struct drbd_device *device = container_of(kref, struct drbd_device, kref);
-	struct drbd_connection *connection = device->connection;
+	struct drbd_connection *connection = first_peer_device(device)->connection;
 
 	del_timer_sync(&device->request_timer);
 
@@ -2190,6 +2192,7 @@
 	put_disk(device->vdisk);
 	blk_cleanup_queue(device->rq_queue);
 	kfree(device->rs_plan_s);
+	kfree(first_peer_device(device));
 	kfree(device);
 
 	kref_put(&connection->kref, &conn_destroy);
@@ -2300,7 +2303,7 @@
 
 	idr_for_each_entry(&minors, device, i) {
 		idr_remove(&minors, device_to_minor(device));
-		idr_remove(&device->connection->volumes, device->vnr);
+		idr_remove(&first_peer_device(device)->connection->volumes, device->vnr);
 		destroy_workqueue(device->submit.wq);
 		del_gendisk(device->vdisk);
 		/* synchronize_rcu(); No other threads running at this point */
@@ -2343,7 +2346,7 @@
 		goto out;
 	}
 
-	if (test_bit(CALLBACK_PENDING, &device->connection->flags)) {
+	if (test_bit(CALLBACK_PENDING, &first_peer_device(device)->connection->flags)) {
 		r |= (1 << BDI_async_congested);
 		/* Without good local data, we would need to read from remote,
 		 * and that would need the worker thread as well, which is
@@ -2367,7 +2370,8 @@
 			reason = 'b';
 	}
 
-	if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &device->connection->flags)) {
+	if (bdi_bits & (1 << BDI_async_congested) &&
+	    test_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags)) {
 		r |= (1 << BDI_async_congested);
 		reason = reason == 'b' ? 'a' : 'n';
 	}
@@ -2606,9 +2610,10 @@
 	return 0;
 }
 
-enum drbd_ret_code conn_new_minor(struct drbd_connection *connection, unsigned int minor, int vnr)
+enum drbd_ret_code drbd_create_minor(struct drbd_connection *connection, unsigned int minor, int vnr)
 {
 	struct drbd_device *device;
+	struct drbd_peer_device *peer_device;
 	struct gendisk *disk;
 	struct request_queue *q;
 	int vnr_got = vnr;
@@ -2623,9 +2628,15 @@
 	device = kzalloc(sizeof(struct drbd_device), GFP_KERNEL);
 	if (!device)
 		return ERR_NOMEM;
+	peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
+	if (!peer_device)
+		goto out_no_peer_device;
 
+	INIT_LIST_HEAD(&device->peer_devices);
+	list_add(&peer_device->peer_devices, &device->peer_devices);
 	kref_get(&connection->kref);
-	device->connection = connection;
+	peer_device->connection = connection;
+	peer_device->device = device;
 
 	device->minor = minor;
 	device->vnr = vnr;
@@ -2666,7 +2677,7 @@
 	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 = &device->connection->req_lock; /* needed since we use */
+	q->queue_lock = &first_peer_device(device)->connection->req_lock; /* needed since we use */
 
 	device->md_io_page = alloc_page(GFP_KERNEL);
 	if (!device->md_io_page)
@@ -2725,8 +2736,9 @@
 out_no_disk:
 	blk_cleanup_queue(q);
 out_no_q:
-	kfree(device);
 	kref_put(&connection->kref, &conn_destroy);
+out_no_peer_device:
+	kfree(device);
 	return err;
 }
 
@@ -3172,14 +3184,14 @@
 
 	rv = NO_ERROR;
 
-	spin_lock_irq(&device->connection->req_lock);
+	spin_lock_irq(&first_peer_device(device)->connection->req_lock);
 	if (device->state.conn < C_CONNECTED) {
 		unsigned int peer;
 		peer = be32_to_cpu(buffer->la_peer_max_bio_size);
 		peer = max(peer, DRBD_MAX_BIO_SIZE_SAFE);
 		device->peer_max_bio_size = peer;
 	}
-	spin_unlock_irq(&device->connection->req_lock);
+	spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
 
  err:
 	drbd_md_put_buffer(device);
@@ -3454,7 +3466,7 @@
 			  void (*done)(struct drbd_device *, int),
 			  char *why, enum bm_flag flags)
 {
-	D_ASSERT(current == device->connection->worker.task);
+	D_ASSERT(current == first_peer_device(device)->connection->worker.task);
 
 	D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &device->flags));
 	D_ASSERT(!test_bit(BITMAP_IO, &device->flags));
@@ -3468,13 +3480,13 @@
 	device->bm_io_work.why = why;
 	device->bm_io_work.flags = flags;
 
-	spin_lock_irq(&device->connection->req_lock);
+	spin_lock_irq(&first_peer_device(device)->connection->req_lock);
 	set_bit(BITMAP_IO, &device->flags);
 	if (atomic_read(&device->ap_bio_cnt) == 0) {
 		if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
-			drbd_queue_work(&device->connection->sender_work, &device->bm_io_work.w);
+			drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
 	}
-	spin_unlock_irq(&device->connection->req_lock);
+	spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
 }
 
 /**
@@ -3491,7 +3503,7 @@
 {
 	int rv;
 
-	D_ASSERT(current != device->connection->worker.task);
+	D_ASSERT(current != first_peer_device(device)->connection->worker.task);
 
 	if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
 		drbd_suspend_io(device);
@@ -3532,7 +3544,7 @@
 
 	/* must not double-queue! */
 	if (list_empty(&device->md_sync_work.list))
-		drbd_queue_work_front(&device->connection->sender_work, &device->md_sync_work);
+		drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &device->md_sync_work);
 }
 
 static int w_md_sync(struct drbd_work *w, int unused)
@@ -3631,7 +3643,7 @@
 	long timeout;
 
 	rcu_read_lock();
-	nc = rcu_dereference(device->connection->net_conf);
+	nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
 	if (!nc) {
 		rcu_read_unlock();
 		return -ETIMEDOUT;
@@ -3642,10 +3654,10 @@
 	/* Indicate to wake up device->misc_wait on progress.  */
 	i->waiting = true;
 	prepare_to_wait(&device->misc_wait, &wait, TASK_INTERRUPTIBLE);
-	spin_unlock_irq(&device->connection->req_lock);
+	spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
 	timeout = schedule_timeout(timeout);
 	finish_wait(&device->misc_wait, &wait);
-	spin_lock_irq(&device->connection->req_lock);
+	spin_lock_irq(&first_peer_device(device)->connection->req_lock);
 	if (!timeout || device->state.conn < C_CONNECTED)
 		return -ETIMEDOUT;
 	if (signal_pending(current))