Commit 257d0af6 authored by Philipp Reisner's avatar Philipp Reisner
Browse files

drbd: Implemented receiving of new style packets on meta socket



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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent fd340c12
Loading
Loading
Loading
Loading
+68 −65
Original line number Diff line number Diff line
@@ -926,18 +926,9 @@ static int drbd_connect(struct drbd_conf *mdev)
	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;
	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);
		*packet_size = be16_to_cpu(h->h80.length);
@@ -951,9 +942,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)
@@ -2807,14 +2814,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);
	}
@@ -3524,7 +3531,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
@@ -3571,7 +3578,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)
@@ -3670,13 +3677,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 },
@@ -4184,9 +4191,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);

@@ -4202,13 +4209,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;
@@ -4218,9 +4225,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);

@@ -4263,9 +4270,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;
@@ -4277,7 +4284,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;
@@ -4304,9 +4311,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 ||
@@ -4337,9 +4344,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));
@@ -4351,11 +4358,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);
@@ -4366,7 +4373,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:
@@ -4382,9 +4389,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));

@@ -4398,9 +4405,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;
@@ -4442,14 +4449,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)
@@ -4458,8 +4465,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 },
@@ -4483,15 +4490,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));

@@ -4581,30 +4589,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)
@@ -4614,7 +4617,7 @@ int drbd_asender(struct drbd_thread *thi)

			buf	 = h;
			received = 0;
			expect	 = sizeof(struct p_header80);
			expect	 = sizeof(struct p_header);
			cmd	 = NULL;
		}
	}