mirror of
https://github.com/torvalds/linux
synced 2024-10-23 03:37:40 +00:00
drbd: struct packet_info to hold information of decoded packets
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
parent
de0ff338d6
commit
77351055b5
|
@ -48,6 +48,12 @@
|
||||||
|
|
||||||
#include "drbd_vli.h"
|
#include "drbd_vli.h"
|
||||||
|
|
||||||
|
struct packet_info {
|
||||||
|
enum drbd_packet cmd;
|
||||||
|
int size;
|
||||||
|
int vnr;
|
||||||
|
};
|
||||||
|
|
||||||
enum finish_epoch {
|
enum finish_epoch {
|
||||||
FE_STILL_LIVE,
|
FE_STILL_LIVE,
|
||||||
FE_DESTROYED,
|
FE_DESTROYED,
|
||||||
|
@ -924,15 +930,15 @@ static int drbd_connect(struct drbd_conf *mdev)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool decode_header(struct drbd_conf *mdev, struct p_header *h,
|
static bool decode_header(struct drbd_conf *mdev, struct p_header *h, struct packet_info *pi)
|
||||||
enum drbd_packet *cmd, unsigned int *packet_size)
|
|
||||||
{
|
{
|
||||||
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);
|
pi->cmd = be16_to_cpu(h->h80.command);
|
||||||
*packet_size = be16_to_cpu(h->h80.length);
|
pi->size = be16_to_cpu(h->h80.length);
|
||||||
} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
|
} else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) {
|
||||||
*cmd = be16_to_cpu(h->h95.command);
|
pi->cmd = be16_to_cpu(h->h95.command);
|
||||||
*packet_size = be32_to_cpu(h->h95.length) & 0x00ffffff;
|
pi->size = be32_to_cpu(h->h95.length) & 0x00ffffff;
|
||||||
|
pi->vnr = 0;
|
||||||
} else {
|
} else {
|
||||||
dev_err(DEV, "magic?? on data m: 0x%08x c: %d l: %d\n",
|
dev_err(DEV, "magic?? on data m: 0x%08x c: %d l: %d\n",
|
||||||
be32_to_cpu(h->h80.magic),
|
be32_to_cpu(h->h80.magic),
|
||||||
|
@ -943,8 +949,7 @@ static bool decode_header(struct drbd_conf *mdev, struct p_header *h,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
|
static int drbd_recv_header(struct drbd_conf *mdev, struct packet_info *pi)
|
||||||
unsigned int *packet_size)
|
|
||||||
{
|
{
|
||||||
struct p_header *h = &mdev->tconn->data.rbuf.header;
|
struct p_header *h = &mdev->tconn->data.rbuf.header;
|
||||||
int r;
|
int r;
|
||||||
|
@ -956,7 +961,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packet *cmd,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = decode_header(mdev, h, cmd, packet_size);
|
r = decode_header(mdev, h, pi);
|
||||||
mdev->tconn->last_received = jiffies;
|
mdev->tconn->last_received = jiffies;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -3580,6 +3585,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
|
||||||
int err;
|
int err;
|
||||||
int ok = false;
|
int ok = false;
|
||||||
struct p_header *h = &mdev->tconn->data.rbuf.header;
|
struct p_header *h = &mdev->tconn->data.rbuf.header;
|
||||||
|
struct packet_info pi;
|
||||||
|
|
||||||
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
|
||||||
|
@ -3633,8 +3639,10 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!drbd_recv_header(mdev, &cmd, &data_size))
|
if (!drbd_recv_header(mdev, &pi))
|
||||||
goto out;
|
goto out;
|
||||||
|
cmd = pi.cmd;
|
||||||
|
data_size = pi.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_bm_xfer_stats(mdev, "receive", &c);
|
INFO_bm_xfer_stats(mdev, "receive", &c);
|
||||||
|
@ -3762,24 +3770,23 @@ static struct data_cmd drbd_cmd_handler[] = {
|
||||||
static void drbdd(struct drbd_conf *mdev)
|
static void drbdd(struct drbd_conf *mdev)
|
||||||
{
|
{
|
||||||
struct p_header *header = &mdev->tconn->data.rbuf.header;
|
struct p_header *header = &mdev->tconn->data.rbuf.header;
|
||||||
unsigned int packet_size;
|
struct packet_info pi;
|
||||||
enum drbd_packet cmd;
|
|
||||||
size_t shs; /* sub header size */
|
size_t shs; /* sub header size */
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
|
while (get_t_state(&mdev->tconn->receiver) == RUNNING) {
|
||||||
drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
|
drbd_thread_current_set_cpu(mdev, &mdev->tconn->receiver);
|
||||||
if (!drbd_recv_header(mdev, &cmd, &packet_size))
|
if (!drbd_recv_header(mdev, &pi))
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
if (unlikely(cmd >= P_MAX_CMD || !drbd_cmd_handler[cmd].function)) {
|
if (unlikely(pi.cmd >= P_MAX_CMD || !drbd_cmd_handler[pi.cmd].function)) {
|
||||||
dev_err(DEV, "unknown packet type %d, l: %d!\n", cmd, packet_size);
|
dev_err(DEV, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
shs = drbd_cmd_handler[cmd].pkt_size - sizeof(struct p_header);
|
shs = drbd_cmd_handler[pi.cmd].pkt_size - sizeof(struct p_header);
|
||||||
if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
|
if (pi.size - shs > 0 && !drbd_cmd_handler[pi.cmd].expect_payload) {
|
||||||
dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
|
dev_err(DEV, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3792,11 +3799,11 @@ static void drbdd(struct drbd_conf *mdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs);
|
rv = drbd_cmd_handler[pi.cmd].function(mdev, pi.cmd, pi.size - shs);
|
||||||
|
|
||||||
if (unlikely(!rv)) {
|
if (unlikely(!rv)) {
|
||||||
dev_err(DEV, "error receiving %s, l: %d!\n",
|
dev_err(DEV, "error receiving %s, l: %d!\n",
|
||||||
cmdname(cmd), packet_size);
|
cmdname(pi.cmd), pi.size);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3989,27 +3996,26 @@ static int drbd_do_handshake(struct drbd_conf *mdev)
|
||||||
/* ASSERT current == mdev->tconn->receiver ... */
|
/* ASSERT current == mdev->tconn->receiver ... */
|
||||||
struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
|
struct p_handshake *p = &mdev->tconn->data.rbuf.handshake;
|
||||||
const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
|
const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80);
|
||||||
unsigned int length;
|
struct packet_info pi;
|
||||||
enum drbd_packet cmd;
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = drbd_send_handshake(mdev->tconn);
|
rv = drbd_send_handshake(mdev->tconn);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rv = drbd_recv_header(mdev, &cmd, &length);
|
rv = drbd_recv_header(mdev, &pi);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (cmd != P_HAND_SHAKE) {
|
if (pi.cmd != P_HAND_SHAKE) {
|
||||||
dev_err(DEV, "expected HandShake packet, received: %s (0x%04x)\n",
|
dev_err(DEV, "expected HandShake packet, received: %s (0x%04x)\n",
|
||||||
cmdname(cmd), cmd);
|
cmdname(pi.cmd), pi.cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length != expect) {
|
if (pi.size != expect) {
|
||||||
dev_err(DEV, "expected HandShake length: %u, received: %u\n",
|
dev_err(DEV, "expected HandShake length: %u, received: %u\n",
|
||||||
expect, length);
|
expect, pi.size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4071,8 +4077,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
|
||||||
unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
|
unsigned int key_len = strlen(mdev->tconn->net_conf->shared_secret);
|
||||||
unsigned int resp_size;
|
unsigned int resp_size;
|
||||||
struct hash_desc desc;
|
struct hash_desc desc;
|
||||||
enum drbd_packet cmd;
|
struct packet_info pi;
|
||||||
unsigned int length;
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
desc.tfm = mdev->tconn->cram_hmac_tfm;
|
desc.tfm = mdev->tconn->cram_hmac_tfm;
|
||||||
|
@ -4092,33 +4097,33 @@ static int drbd_do_auth(struct drbd_conf *mdev)
|
||||||
if (!rv)
|
if (!rv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
rv = drbd_recv_header(mdev, &cmd, &length);
|
rv = drbd_recv_header(mdev, &pi);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (cmd != P_AUTH_CHALLENGE) {
|
if (pi.cmd != P_AUTH_CHALLENGE) {
|
||||||
dev_err(DEV, "expected AuthChallenge packet, received: %s (0x%04x)\n",
|
dev_err(DEV, "expected AuthChallenge packet, received: %s (0x%04x)\n",
|
||||||
cmdname(cmd), cmd);
|
cmdname(pi.cmd), pi.cmd);
|
||||||
rv = 0;
|
rv = 0;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length > CHALLENGE_LEN * 2) {
|
if (pi.size > CHALLENGE_LEN * 2) {
|
||||||
dev_err(DEV, "expected AuthChallenge payload too big.\n");
|
dev_err(DEV, "expected AuthChallenge payload too big.\n");
|
||||||
rv = -1;
|
rv = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers_ch = kmalloc(length, GFP_NOIO);
|
peers_ch = kmalloc(pi.size, GFP_NOIO);
|
||||||
if (peers_ch == NULL) {
|
if (peers_ch == NULL) {
|
||||||
dev_err(DEV, "kmalloc of peers_ch failed\n");
|
dev_err(DEV, "kmalloc of peers_ch failed\n");
|
||||||
rv = -1;
|
rv = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = drbd_recv(mdev->tconn, peers_ch, length);
|
rv = drbd_recv(mdev->tconn, peers_ch, pi.size);
|
||||||
|
|
||||||
if (rv != length) {
|
if (rv != pi.size) {
|
||||||
if (!signal_pending(current))
|
if (!signal_pending(current))
|
||||||
dev_warn(DEV, "short read AuthChallenge: l=%u\n", rv);
|
dev_warn(DEV, "short read AuthChallenge: l=%u\n", rv);
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
@ -4134,7 +4139,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_init_table(&sg, 1);
|
sg_init_table(&sg, 1);
|
||||||
sg_set_buf(&sg, peers_ch, length);
|
sg_set_buf(&sg, peers_ch, pi.size);
|
||||||
|
|
||||||
rv = crypto_hash_digest(&desc, &sg, sg.length, response);
|
rv = crypto_hash_digest(&desc, &sg, sg.length, response);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
|
@ -4147,18 +4152,18 @@ static int drbd_do_auth(struct drbd_conf *mdev)
|
||||||
if (!rv)
|
if (!rv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
rv = drbd_recv_header(mdev, &cmd, &length);
|
rv = drbd_recv_header(mdev, &pi);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (cmd != P_AUTH_RESPONSE) {
|
if (pi.cmd != P_AUTH_RESPONSE) {
|
||||||
dev_err(DEV, "expected AuthResponse packet, received: %s (0x%04x)\n",
|
dev_err(DEV, "expected AuthResponse packet, received: %s (0x%04x)\n",
|
||||||
cmdname(cmd), cmd);
|
cmdname(pi.cmd), pi.cmd);
|
||||||
rv = 0;
|
rv = 0;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length != resp_size) {
|
if (pi.size != resp_size) {
|
||||||
dev_err(DEV, "expected AuthResponse payload of wrong size\n");
|
dev_err(DEV, "expected AuthResponse payload of wrong size\n");
|
||||||
rv = 0;
|
rv = 0;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -4544,14 +4549,14 @@ int drbd_asender(struct drbd_thread *thi)
|
||||||
struct drbd_conf *mdev = thi->mdev;
|
struct drbd_conf *mdev = thi->mdev;
|
||||||
struct p_header *h = &mdev->tconn->meta.rbuf.header;
|
struct p_header *h = &mdev->tconn->meta.rbuf.header;
|
||||||
struct asender_cmd *cmd = NULL;
|
struct asender_cmd *cmd = NULL;
|
||||||
|
struct packet_info pi;
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
void *buf = h;
|
void *buf = h;
|
||||||
int received = 0;
|
int received = 0;
|
||||||
int expect = sizeof(struct p_header);
|
int expect = sizeof(struct p_header);
|
||||||
int ping_timeout_active = 0;
|
int ping_timeout_active = 0;
|
||||||
int empty, pkt_size;
|
int empty;
|
||||||
enum drbd_packet cmd_nr;
|
|
||||||
|
|
||||||
sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
|
sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
|
||||||
|
|
||||||
|
@ -4640,25 +4645,25 @@ int drbd_asender(struct drbd_thread *thi)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (received == expect && cmd == NULL) {
|
if (received == expect && cmd == NULL) {
|
||||||
if (!decode_header(mdev, h, &cmd_nr, &pkt_size))
|
if (!decode_header(mdev, h, &pi))
|
||||||
goto reconnect;
|
goto reconnect;
|
||||||
cmd = get_asender_cmd(cmd_nr);
|
cmd = get_asender_cmd(pi.cmd);
|
||||||
if (unlikely(cmd == NULL)) {
|
if (unlikely(cmd == NULL)) {
|
||||||
dev_err(DEV, "unknown command %d on meta (l: %d)\n",
|
dev_err(DEV, "unknown command %d on meta (l: %d)\n",
|
||||||
cmd_nr, pkt_size);
|
pi.cmd, pi.size);
|
||||||
goto disconnect;
|
goto disconnect;
|
||||||
}
|
}
|
||||||
expect = cmd->pkt_size;
|
expect = cmd->pkt_size;
|
||||||
if (pkt_size != expect - sizeof(struct p_header)) {
|
if (pi.size != expect - sizeof(struct p_header)) {
|
||||||
dev_err(DEV, "Wrong packet size on meta (c: %d, l: %d)\n",
|
dev_err(DEV, "Wrong packet size on meta (c: %d, l: %d)\n",
|
||||||
cmd_nr, pkt_size);
|
pi.cmd, pi.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, cmd_nr))
|
if (!cmd->process(mdev, pi.cmd))
|
||||||
goto reconnect;
|
goto reconnect;
|
||||||
|
|
||||||
/* the idle_timeout (ping-int)
|
/* the idle_timeout (ping-int)
|
||||||
|
|
Loading…
Reference in a new issue