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: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
Philipp Reisner 2011-01-26 12:15:29 +01:00
Родитель fd340c12c9
Коммит 257d0af689
1 изменённых файлов: 68 добавлений и 65 удалений

Просмотреть файл

@ -926,18 +926,9 @@ 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;
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;
}
}