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:
Родитель
fd340c12c9
Коммит
257d0af689
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче