aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_receiver.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-03-25 10:37:43 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:44:59 -0500
commit1952e9166a335b552ecb5964c1fb4609bd999de8 (patch)
tree14182fd72b9581163ea8458e94a1fa67d4fa9ae7 /drivers/block/drbd/drbd_receiver.c
parente05e1e59db07b2a7f493c0219230a7be13f87f9d (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.c137
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
63enum mdev_or_conn {
64 MDEV,
65 CONN,
66};
67
68static int drbd_do_handshake(struct drbd_tconn *tconn); 63static int drbd_do_handshake(struct drbd_tconn *tconn);
69static int drbd_do_auth(struct drbd_tconn *tconn); 64static int drbd_do_auth(struct drbd_tconn *tconn);
70static int drbd_disconnected(int vnr, void *p, void *data); 65static 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
4479static int got_RqSReply(struct drbd_conf *mdev, struct packet_info *pi) 4474static 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
4512static int got_IsInSync(struct drbd_conf *mdev, struct packet_info *pi) 4512static 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
4557static int got_BlockAck(struct drbd_conf *mdev, struct packet_info *pi) 4562static 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
4602static int got_NegAck(struct drbd_conf *mdev, struct packet_info *pi) 4612static 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
4635static int got_NegDReply(struct drbd_conf *mdev, struct packet_info *pi) 4650static 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
4650static int got_NegRSDReply(struct drbd_conf *mdev, struct packet_info *pi) 4670static 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
4681static int got_BarrierAck(struct drbd_conf *mdev, struct packet_info *pi) 4706static 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
4697static int got_OVResult(struct drbd_conf *mdev, struct packet_info *pi) 4727static 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
4742static int got_skip(struct drbd_conf *mdev, struct packet_info *pi) 4777static 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
4773struct asender_cmd { 4808struct 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
4782static struct asender_cmd asender_tbl[] = { 4813static 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
4802int drbd_asender(struct drbd_thread *thi) 4833int 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