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
parent fd340c12c9
commit 257d0af689

View File

@ -926,18 +926,9 @@ static int drbd_connect(struct drbd_conf *mdev)
return -1; 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)) { if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) {
*cmd = be16_to_cpu(h->h80.command); *cmd = be16_to_cpu(h->h80.command);
*packet_size = be16_to_cpu(h->h80.length); *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)); be16_to_cpu(h->h80.length));
return false; 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; mdev->tconn->last_received = jiffies;
return true; return r;
} }
static void drbd_flush(struct drbd_conf *mdev) 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) { 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; data_size = packet_size - header_size;
} else if (apv <= 94) { } 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; data_size = packet_size - header_size;
D_ASSERT(data_size == 0); D_ASSERT(data_size == 0);
} else { } 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; data_size = packet_size - header_size;
D_ASSERT(data_size == 0); D_ASSERT(data_size == 0);
} }
@ -3524,7 +3531,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
void *buffer; void *buffer;
int err; int err;
int ok = false; 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); drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
/* you are supposed to send additional out-of-sync information /* 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.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) {
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_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply },
[P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } , [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } ,
[P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } , [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } ,
[P_BITMAP] = { 1, sizeof(struct p_header80), receive_bitmap } , [P_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
[P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header80), receive_bitmap } , [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } ,
[P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header80), receive_UnplugRemote }, [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), receive_UnplugRemote },
[P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest },
[P_RS_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_PARAM] = { 1, sizeof(struct p_header), receive_SyncParam },
[P_SYNC_PARAM89] = { 1, sizeof(struct p_header80), receive_SyncParam }, [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), receive_SyncParam },
[P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol }, [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol },
[P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids }, [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids },
[P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes }, [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes },
@ -4184,9 +4191,9 @@ int drbdd_init(struct drbd_thread *thi)
/* ********* acknowledge sender ******** */ /* ********* 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); 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; 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); 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 */ /* restore idle timeout */
mdev->tconn->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;
@ -4218,9 +4225,9 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header80 *h)
return true; 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); sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize); 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; 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); sector_t sector = be64_to_cpu(p->sector);
int blksize = be32_to_cpu(p->blksize); int blksize = be32_to_cpu(p->blksize);
enum drbd_req_event what; 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); dec_rs_pending(mdev);
return true; return true;
} }
switch (be16_to_cpu(h->command)) { switch (cmd) {
case P_RS_WRITE_ACK: case P_RS_WRITE_ACK:
D_ASSERT(mdev->tconn->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; 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); 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); sector_t sector = be64_to_cpu(p->sector);
int size = be32_to_cpu(p->blksize); int size = be32_to_cpu(p->blksize);
bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A || 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; 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); sector_t sector = be64_to_cpu(p->sector);
update_peer_seq(mdev, be32_to_cpu(p->seq_num)); 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); 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; sector_t sector;
int size; 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); sector = be64_to_cpu(p->sector);
size = be32_to_cpu(p->blksize); 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)) { if (get_ldev_if_state(mdev, D_FAILED)) {
drbd_rs_complete_io(mdev, sector); drbd_rs_complete_io(mdev, sector);
switch (be16_to_cpu(h->command)) { switch (cmd) {
case P_NEG_RS_DREPLY: case P_NEG_RS_DREPLY:
drbd_rs_failed_io(mdev, sector, size); drbd_rs_failed_io(mdev, sector, size);
case P_RS_CANCEL: case P_RS_CANCEL:
@ -4382,9 +4389,9 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
return true; 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)); 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; 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; struct drbd_work *w;
sector_t sector; sector_t sector;
int size; int size;
@ -4442,14 +4449,14 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header80 *h)
return true; 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; return true;
} }
struct asender_cmd { struct asender_cmd {
size_t pkt_size; 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) 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 /* anything missing from this table is in
* the drbd_cmd_handler (drbd_default_handler) table, * the drbd_cmd_handler (drbd_default_handler) table,
* see the beginning of drbdd() */ * see the beginning of drbdd() */
[P_PING] = { sizeof(struct p_header80), got_Ping }, [P_PING] = { sizeof(struct p_header), got_Ping },
[P_PING_ACK] = { sizeof(struct p_header80), got_PingAck }, [P_PING_ACK] = { sizeof(struct p_header), got_PingAck },
[P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, [P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck },
[P_WRITE_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 }, [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) int drbd_asender(struct drbd_thread *thi)
{ {
struct drbd_conf *mdev = thi->mdev; 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; struct asender_cmd *cmd = NULL;
int rv, len; int rv;
void *buf = h; void *buf = h;
int received = 0; int received = 0;
int expect = sizeof(struct p_header80); int expect = sizeof(struct p_header);
int empty;
int ping_timeout_active = 0; int ping_timeout_active = 0;
int empty, pkt_size;
enum drbd_packets cmd_nr;
sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev)); 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 (received == expect && cmd == NULL) {
if (unlikely(h->magic != cpu_to_be32(DRBD_MAGIC))) { if (!decode_header(mdev, h, &cmd_nr, &pkt_size))
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));
goto reconnect; goto reconnect;
} cmd = get_asender_cmd(cmd_nr);
cmd = get_asender_cmd(be16_to_cpu(h->command));
len = be16_to_cpu(h->length);
if (unlikely(cmd == NULL)) { if (unlikely(cmd == NULL)) {
dev_err(DEV, "unknown command?? on meta m: 0x%08x c: %d l: %d\n", dev_err(DEV, "unknown command %d on meta (l: %d)\n",
be32_to_cpu(h->magic), cmd_nr, pkt_size);
be16_to_cpu(h->command),
be16_to_cpu(h->length));
goto disconnect; goto disconnect;
} }
expect = cmd->pkt_size; 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; goto reconnect;
}
} }
if (received == expect) { if (received == expect) {
mdev->tconn->last_received = jiffies; mdev->tconn->last_received = jiffies;
D_ASSERT(cmd != NULL); D_ASSERT(cmd != NULL);
if (!cmd->process(mdev, h)) if (!cmd->process(mdev, cmd_nr))
goto reconnect; goto reconnect;
/* the idle_timeout (ping-int) /* the idle_timeout (ping-int)
@ -4614,7 +4617,7 @@ int drbd_asender(struct drbd_thread *thi)
buf = h; buf = h;
received = 0; received = 0;
expect = sizeof(struct p_header80); expect = sizeof(struct p_header);
cmd = NULL; cmd = NULL;
} }
} }