diff options
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 113 |
1 files changed, 18 insertions, 95 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index cba1deb..20abef5 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3555,14 +3555,15 @@ static int receive_bitmap(struct drbd_conf *mdev, struct p_header *h) return ok; } -static int receive_skip(struct drbd_conf *mdev, struct p_header *h) +static int receive_skip_(struct drbd_conf *mdev, struct p_header *h, int silent) { /* TODO zero copy sink :) */ static char sink[128]; int size, want, r; - dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", - h->command, h->length); + if (!silent) + dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", + h->command, h->length); size = h->length; while (size > 0) { @@ -3574,101 +3575,25 @@ static int receive_skip(struct drbd_conf *mdev, struct p_header *h) return size == 0; } -static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) -{ - if (mdev->state.disk >= D_INCONSISTENT) - drbd_kick_lo(mdev); - - /* Make sure we've acked all the TCP data associated - * with the data requests being unplugged */ - drbd_tcp_quickack(mdev->data.socket); - - return TRUE; -} - -static void timeval_sub_us(struct timeval* tv, unsigned int us) +static int receive_skip(struct drbd_conf *mdev, struct p_header *h) { - tv->tv_sec -= us / 1000000; - us = us % 1000000; - if (tv->tv_usec > us) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - tv->tv_usec -= us; + return receive_skip_(mdev, h, 0); } -static void got_delay_probe(struct drbd_conf *mdev, int from, struct p_delay_probe *p) +static int receive_skip_silent(struct drbd_conf *mdev, struct p_header *h) { - struct delay_probe *dp; - struct list_head *le; - struct timeval now; - int seq_num; - int offset; - int data_delay; - - seq_num = be32_to_cpu(p->seq_num); - offset = be32_to_cpu(p->offset); - - spin_lock(&mdev->peer_seq_lock); - if (!list_empty(&mdev->delay_probes)) { - if (from == USE_DATA_SOCKET) - le = mdev->delay_probes.next; - else - le = mdev->delay_probes.prev; - - dp = list_entry(le, struct delay_probe, list); - - if (dp->seq_num == seq_num) { - list_del(le); - spin_unlock(&mdev->peer_seq_lock); - do_gettimeofday(&now); - timeval_sub_us(&now, offset); - data_delay = - now.tv_usec - dp->time.tv_usec + - (now.tv_sec - dp->time.tv_sec) * 1000000; - - if (data_delay > 0) - mdev->data_delay = data_delay; - - kfree(dp); - return; - } - - if (dp->seq_num > seq_num) { - spin_unlock(&mdev->peer_seq_lock); - dev_warn(DEV, "Previous allocation failure of struct delay_probe?\n"); - return; /* Do not alloca a struct delay_probe.... */ - } - } - spin_unlock(&mdev->peer_seq_lock); - - dp = kmalloc(sizeof(struct delay_probe), GFP_NOIO); - if (!dp) { - dev_warn(DEV, "Failed to allocate a struct delay_probe, do not worry.\n"); - return; - } - - dp->seq_num = seq_num; - do_gettimeofday(&dp->time); - timeval_sub_us(&dp->time, offset); - - spin_lock(&mdev->peer_seq_lock); - if (from == USE_DATA_SOCKET) - list_add(&dp->list, &mdev->delay_probes); - else - list_add_tail(&dp->list, &mdev->delay_probes); - spin_unlock(&mdev->peer_seq_lock); + return receive_skip_(mdev, h, 1); } -static int receive_delay_probe(struct drbd_conf *mdev, struct p_header *h) +static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) { - struct p_delay_probe *p = (struct p_delay_probe *)h; + if (mdev->state.disk >= D_INCONSISTENT) + drbd_kick_lo(mdev); - ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; - if (drbd_recv(mdev, h->payload, h->length) != h->length) - return FALSE; + /* Make sure we've acked all the TCP data associated + * with the data requests being unplugged */ + drbd_tcp_quickack(mdev->data.socket); - got_delay_probe(mdev, USE_DATA_SOCKET, p); return TRUE; } @@ -3695,7 +3620,7 @@ static drbd_cmd_handler_f drbd_default_handler[] = { [P_OV_REQUEST] = receive_DataRequest, [P_OV_REPLY] = receive_DataRequest, [P_CSUM_RS_REQUEST] = receive_DataRequest, - [P_DELAY_PROBE] = receive_delay_probe, + [P_DELAY_PROBE] = receive_skip_silent, /* anything missing from this table is in * the asender_tbl, see get_asender_cmd */ [P_MAX_CMD] = NULL, @@ -4472,11 +4397,9 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header *h) return TRUE; } -static int got_delay_probe_m(struct drbd_conf *mdev, struct p_header *h) +static int got_something_to_ignore_m(struct drbd_conf *mdev, struct p_header *h) { - struct p_delay_probe *p = (struct p_delay_probe *)h; - - got_delay_probe(mdev, USE_META_SOCKET, p); + /* IGNORE */ return TRUE; } @@ -4504,7 +4427,7 @@ static struct asender_cmd *get_asender_cmd(int cmd) [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, - [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_delay_probe_m }, + [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_something_to_ignore_m }, [P_MAX_CMD] = { 0, NULL }, }; if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) |