diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-03-25 10:37:43 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:44:59 -0500 |
commit | 1952e9166a335b552ecb5964c1fb4609bd999de8 (patch) | |
tree | 14182fd72b9581163ea8458e94a1fa67d4fa9ae7 /drivers/block/drbd/drbd_receiver.c | |
parent | e05e1e59db07b2a7f493c0219230a7be13f87f9d (diff) |
drbd: Map from (connection, volume number) to device in the asender handlers
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 137 |
1 files changed, 82 insertions, 55 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 232ca28cb99b..b7cb7590e298 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -60,11 +60,6 @@ enum finish_epoch { | |||
60 | FE_RECYCLED, | 60 | FE_RECYCLED, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | enum mdev_or_conn { | ||
64 | MDEV, | ||
65 | CONN, | ||
66 | }; | ||
67 | |||
68 | static int drbd_do_handshake(struct drbd_tconn *tconn); | 63 | static int drbd_do_handshake(struct drbd_tconn *tconn); |
69 | static int drbd_do_auth(struct drbd_tconn *tconn); | 64 | static int drbd_do_auth(struct drbd_tconn *tconn); |
70 | static int drbd_disconnected(int vnr, void *p, void *data); | 65 | static int drbd_disconnected(int vnr, void *p, void *data); |
@@ -4476,11 +4471,16 @@ static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4476 | return true; | 4471 | return true; |
4477 | } | 4472 | } |
4478 | 4473 | ||
4479 | static int got_RqSReply(struct drbd_conf *mdev, struct packet_info *pi) | 4474 | static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4480 | { | 4475 | { |
4481 | struct p_req_state_reply *p = mdev->tconn->meta.rbuf; | 4476 | struct drbd_conf *mdev; |
4477 | struct p_req_state_reply *p = tconn->meta.rbuf; | ||
4482 | int retcode = be32_to_cpu(p->retcode); | 4478 | int retcode = be32_to_cpu(p->retcode); |
4483 | 4479 | ||
4480 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4481 | if (!mdev) | ||
4482 | return false; | ||
4483 | |||
4484 | if (retcode >= SS_SUCCESS) { | 4484 | if (retcode >= SS_SUCCESS) { |
4485 | set_bit(CL_ST_CHG_SUCCESS, &mdev->flags); | 4485 | set_bit(CL_ST_CHG_SUCCESS, &mdev->flags); |
4486 | } else { | 4486 | } else { |
@@ -4509,12 +4509,17 @@ static int got_PingAck(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4509 | return true; | 4509 | return true; |
4510 | } | 4510 | } |
4511 | 4511 | ||
4512 | static int got_IsInSync(struct drbd_conf *mdev, struct packet_info *pi) | 4512 | static int got_IsInSync(struct drbd_tconn *tconn, struct packet_info *pi) |
4513 | { | 4513 | { |
4514 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4514 | struct drbd_conf *mdev; |
4515 | struct p_block_ack *p = tconn->meta.rbuf; | ||
4515 | sector_t sector = be64_to_cpu(p->sector); | 4516 | sector_t sector = be64_to_cpu(p->sector); |
4516 | int blksize = be32_to_cpu(p->blksize); | 4517 | int blksize = be32_to_cpu(p->blksize); |
4517 | 4518 | ||
4519 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4520 | if (!mdev) | ||
4521 | return false; | ||
4522 | |||
4518 | D_ASSERT(mdev->tconn->agreed_pro_version >= 89); | 4523 | D_ASSERT(mdev->tconn->agreed_pro_version >= 89); |
4519 | 4524 | ||
4520 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); | 4525 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); |
@@ -4554,13 +4559,18 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector, | |||
4554 | return true; | 4559 | return true; |
4555 | } | 4560 | } |
4556 | 4561 | ||
4557 | static int got_BlockAck(struct drbd_conf *mdev, struct packet_info *pi) | 4562 | static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4558 | { | 4563 | { |
4559 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4564 | struct drbd_conf *mdev; |
4565 | struct p_block_ack *p = tconn->meta.rbuf; | ||
4560 | sector_t sector = be64_to_cpu(p->sector); | 4566 | sector_t sector = be64_to_cpu(p->sector); |
4561 | int blksize = be32_to_cpu(p->blksize); | 4567 | int blksize = be32_to_cpu(p->blksize); |
4562 | enum drbd_req_event what; | 4568 | enum drbd_req_event what; |
4563 | 4569 | ||
4570 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4571 | if (!mdev) | ||
4572 | return false; | ||
4573 | |||
4564 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); | 4574 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); |
4565 | 4575 | ||
4566 | if (p->block_id == ID_SYNCER) { | 4576 | if (p->block_id == ID_SYNCER) { |
@@ -4599,15 +4609,20 @@ static int got_BlockAck(struct drbd_conf *mdev, struct packet_info *pi) | |||
4599 | what, false); | 4609 | what, false); |
4600 | } | 4610 | } |
4601 | 4611 | ||
4602 | static int got_NegAck(struct drbd_conf *mdev, struct packet_info *pi) | 4612 | static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4603 | { | 4613 | { |
4604 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4614 | struct drbd_conf *mdev; |
4615 | struct p_block_ack *p = tconn->meta.rbuf; | ||
4605 | sector_t sector = be64_to_cpu(p->sector); | 4616 | sector_t sector = be64_to_cpu(p->sector); |
4606 | int size = be32_to_cpu(p->blksize); | 4617 | int size = be32_to_cpu(p->blksize); |
4607 | bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A || | 4618 | bool missing_ok = tconn->net_conf->wire_protocol == DRBD_PROT_A || |
4608 | mdev->tconn->net_conf->wire_protocol == DRBD_PROT_B; | 4619 | tconn->net_conf->wire_protocol == DRBD_PROT_B; |
4609 | bool found; | 4620 | bool found; |
4610 | 4621 | ||
4622 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4623 | if (!mdev) | ||
4624 | return false; | ||
4625 | |||
4611 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); | 4626 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); |
4612 | 4627 | ||
4613 | if (p->block_id == ID_SYNCER) { | 4628 | if (p->block_id == ID_SYNCER) { |
@@ -4632,11 +4647,16 @@ static int got_NegAck(struct drbd_conf *mdev, struct packet_info *pi) | |||
4632 | return true; | 4647 | return true; |
4633 | } | 4648 | } |
4634 | 4649 | ||
4635 | static int got_NegDReply(struct drbd_conf *mdev, struct packet_info *pi) | 4650 | static int got_NegDReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4636 | { | 4651 | { |
4637 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4652 | struct drbd_conf *mdev; |
4653 | struct p_block_ack *p = tconn->meta.rbuf; | ||
4638 | sector_t sector = be64_to_cpu(p->sector); | 4654 | sector_t sector = be64_to_cpu(p->sector); |
4639 | 4655 | ||
4656 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4657 | if (!mdev) | ||
4658 | return false; | ||
4659 | |||
4640 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); | 4660 | update_peer_seq(mdev, be32_to_cpu(p->seq_num)); |
4641 | 4661 | ||
4642 | dev_err(DEV, "Got NegDReply; Sector %llus, len %u; Fail original request.\n", | 4662 | dev_err(DEV, "Got NegDReply; Sector %llus, len %u; Fail original request.\n", |
@@ -4647,11 +4667,16 @@ static int got_NegDReply(struct drbd_conf *mdev, struct packet_info *pi) | |||
4647 | NEG_ACKED, false); | 4667 | NEG_ACKED, false); |
4648 | } | 4668 | } |
4649 | 4669 | ||
4650 | static int got_NegRSDReply(struct drbd_conf *mdev, struct packet_info *pi) | 4670 | static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4651 | { | 4671 | { |
4672 | struct drbd_conf *mdev; | ||
4652 | sector_t sector; | 4673 | sector_t sector; |
4653 | int size; | 4674 | int size; |
4654 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4675 | struct p_block_ack *p = tconn->meta.rbuf; |
4676 | |||
4677 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4678 | if (!mdev) | ||
4679 | return false; | ||
4655 | 4680 | ||
4656 | sector = be64_to_cpu(p->sector); | 4681 | sector = be64_to_cpu(p->sector); |
4657 | size = be32_to_cpu(p->blksize); | 4682 | size = be32_to_cpu(p->blksize); |
@@ -4678,9 +4703,14 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct packet_info *pi) | |||
4678 | return true; | 4703 | return true; |
4679 | } | 4704 | } |
4680 | 4705 | ||
4681 | static int got_BarrierAck(struct drbd_conf *mdev, struct packet_info *pi) | 4706 | static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4682 | { | 4707 | { |
4683 | struct p_barrier_ack *p = mdev->tconn->meta.rbuf; | 4708 | struct drbd_conf *mdev; |
4709 | struct p_barrier_ack *p = tconn->meta.rbuf; | ||
4710 | |||
4711 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4712 | if (!mdev) | ||
4713 | return false; | ||
4684 | 4714 | ||
4685 | tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size)); | 4715 | tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size)); |
4686 | 4716 | ||
@@ -4694,13 +4724,18 @@ static int got_BarrierAck(struct drbd_conf *mdev, struct packet_info *pi) | |||
4694 | return true; | 4724 | return true; |
4695 | } | 4725 | } |
4696 | 4726 | ||
4697 | static int got_OVResult(struct drbd_conf *mdev, struct packet_info *pi) | 4727 | static int got_OVResult(struct drbd_tconn *tconn, struct packet_info *pi) |
4698 | { | 4728 | { |
4699 | struct p_block_ack *p = mdev->tconn->meta.rbuf; | 4729 | struct drbd_conf *mdev; |
4730 | struct p_block_ack *p = tconn->meta.rbuf; | ||
4700 | struct drbd_work *w; | 4731 | struct drbd_work *w; |
4701 | sector_t sector; | 4732 | sector_t sector; |
4702 | int size; | 4733 | int size; |
4703 | 4734 | ||
4735 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
4736 | if (!mdev) | ||
4737 | return false; | ||
4738 | |||
4704 | sector = be64_to_cpu(p->sector); | 4739 | sector = be64_to_cpu(p->sector); |
4705 | size = be32_to_cpu(p->blksize); | 4740 | size = be32_to_cpu(p->blksize); |
4706 | 4741 | ||
@@ -4739,7 +4774,7 @@ static int got_OVResult(struct drbd_conf *mdev, struct packet_info *pi) | |||
4739 | return true; | 4774 | return true; |
4740 | } | 4775 | } |
4741 | 4776 | ||
4742 | static int got_skip(struct drbd_conf *mdev, struct packet_info *pi) | 4777 | static int got_skip(struct drbd_tconn *tconn, struct packet_info *pi) |
4743 | { | 4778 | { |
4744 | return true; | 4779 | return true; |
4745 | } | 4780 | } |
@@ -4772,31 +4807,27 @@ static int tconn_process_done_ee(struct drbd_tconn *tconn) | |||
4772 | 4807 | ||
4773 | struct asender_cmd { | 4808 | struct asender_cmd { |
4774 | size_t pkt_size; | 4809 | size_t pkt_size; |
4775 | enum mdev_or_conn fa_type; /* first argument's type */ | 4810 | int (*fn)(struct drbd_tconn *tconn, struct packet_info *); |
4776 | union { | ||
4777 | int (*mdev_fn)(struct drbd_conf *mdev, struct packet_info *); | ||
4778 | int (*conn_fn)(struct drbd_tconn *tconn, struct packet_info *); | ||
4779 | }; | ||
4780 | }; | 4811 | }; |
4781 | 4812 | ||
4782 | static struct asender_cmd asender_tbl[] = { | 4813 | static struct asender_cmd asender_tbl[] = { |
4783 | [P_PING] = { sizeof(struct p_header), CONN, { .conn_fn = got_Ping } }, | 4814 | [P_PING] = { sizeof(struct p_header), got_Ping }, |
4784 | [P_PING_ACK] = { sizeof(struct p_header), CONN, { .conn_fn = got_PingAck } }, | 4815 | [P_PING_ACK] = { sizeof(struct p_header), got_PingAck }, |
4785 | [P_RECV_ACK] = { sizeof(struct p_block_ack), MDEV, { got_BlockAck } }, | 4816 | [P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
4786 | [P_WRITE_ACK] = { sizeof(struct p_block_ack), MDEV, { got_BlockAck } }, | 4817 | [P_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
4787 | [P_RS_WRITE_ACK] = { sizeof(struct p_block_ack), MDEV, { got_BlockAck } }, | 4818 | [P_RS_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
4788 | [P_DISCARD_WRITE] = { sizeof(struct p_block_ack), MDEV, { got_BlockAck } }, | 4819 | [P_DISCARD_WRITE] = { sizeof(struct p_block_ack), got_BlockAck }, |
4789 | [P_NEG_ACK] = { sizeof(struct p_block_ack), MDEV, { got_NegAck } }, | 4820 | [P_NEG_ACK] = { sizeof(struct p_block_ack), got_NegAck }, |
4790 | [P_NEG_DREPLY] = { sizeof(struct p_block_ack), MDEV, { got_NegDReply } }, | 4821 | [P_NEG_DREPLY] = { sizeof(struct p_block_ack), got_NegDReply }, |
4791 | [P_NEG_RS_DREPLY] = { sizeof(struct p_block_ack), MDEV, { got_NegRSDReply } }, | 4822 | [P_NEG_RS_DREPLY] = { sizeof(struct p_block_ack), got_NegRSDReply }, |
4792 | [P_OV_RESULT] = { sizeof(struct p_block_ack), MDEV, { got_OVResult } }, | 4823 | [P_OV_RESULT] = { sizeof(struct p_block_ack), got_OVResult }, |
4793 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), MDEV, { got_BarrierAck } }, | 4824 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, |
4794 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), MDEV, { got_RqSReply } }, | 4825 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, |
4795 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), MDEV, { got_IsInSync } }, | 4826 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, |
4796 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe93), MDEV, { got_skip } }, | 4827 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe93), got_skip }, |
4797 | [P_RS_CANCEL] = { sizeof(struct p_block_ack), MDEV, { got_NegRSDReply } }, | 4828 | [P_RS_CANCEL] = { sizeof(struct p_block_ack), got_NegRSDReply }, |
4798 | [P_CONN_ST_CHG_REPLY]={ sizeof(struct p_req_state_reply), CONN, {.conn_fn = got_conn_RqSReply}}, | 4829 | [P_CONN_ST_CHG_REPLY]={ sizeof(struct p_req_state_reply), got_conn_RqSReply }, |
4799 | [P_RETRY_WRITE] = { sizeof(struct p_block_ack), MDEV, { got_BlockAck } }, | 4830 | [P_RETRY_WRITE] = { sizeof(struct p_block_ack), got_BlockAck }, |
4800 | }; | 4831 | }; |
4801 | 4832 | ||
4802 | int drbd_asender(struct drbd_thread *thi) | 4833 | int drbd_asender(struct drbd_thread *thi) |
@@ -4886,7 +4917,7 @@ int drbd_asender(struct drbd_thread *thi) | |||
4886 | if (decode_header(tconn, h, &pi)) | 4917 | if (decode_header(tconn, h, &pi)) |
4887 | goto reconnect; | 4918 | goto reconnect; |
4888 | cmd = &asender_tbl[pi.cmd]; | 4919 | cmd = &asender_tbl[pi.cmd]; |
4889 | if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd) { | 4920 | if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) { |
4890 | conn_err(tconn, "unknown command %d on meta (l: %d)\n", | 4921 | conn_err(tconn, "unknown command %d on meta (l: %d)\n", |
4891 | pi.cmd, pi.size); | 4922 | pi.cmd, pi.size); |
4892 | goto disconnect; | 4923 | goto disconnect; |
@@ -4901,15 +4932,11 @@ int drbd_asender(struct drbd_thread *thi) | |||
4901 | if (received == expect) { | 4932 | if (received == expect) { |
4902 | bool rv; | 4933 | bool rv; |
4903 | 4934 | ||
4904 | if (cmd->fa_type == CONN) { | 4935 | rv = cmd->fn(tconn, &pi); |
4905 | rv = cmd->conn_fn(tconn, &pi); | 4936 | if (!rv) { |
4906 | } else { | 4937 | conn_err(tconn, "%pf failed\n", cmd->fn); |
4907 | struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr); | ||
4908 | rv = cmd->mdev_fn(mdev, &pi); | ||
4909 | } | ||
4910 | |||
4911 | if (!rv) | ||
4912 | goto reconnect; | 4938 | goto reconnect; |
4939 | } | ||
4913 | 4940 | ||
4914 | tconn->last_received = jiffies; | 4941 | tconn->last_received = jiffies; |
4915 | 4942 | ||