diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-03-26 14:55:17 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:58:25 -0500 |
commit | 9ed57dcbda37a1a1fb25ccda4206cc417e54e813 (patch) | |
tree | 90ba7da0f3a11df687b6e53b95460f77b4d58df9 /drivers/block/drbd | |
parent | 648e46b531006b069c66f171151819d10b423c26 (diff) |
drbd: ignore volume number for drbd barrier packet exchange
Transfer log epochs, and therefore P_BARRIER packets,
are per resource, not per volume.
We must not associate them with "some random volume".
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 4 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 10 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 53 |
3 files changed, 31 insertions, 36 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index ab9926e915cb..85769085485d 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -584,7 +584,7 @@ struct drbd_tl_epoch { | |||
584 | }; | 584 | }; |
585 | 585 | ||
586 | struct drbd_epoch { | 586 | struct drbd_epoch { |
587 | struct drbd_conf *mdev; | 587 | struct drbd_tconn *tconn; |
588 | struct list_head list; | 588 | struct list_head list; |
589 | unsigned int barrier_nr; | 589 | unsigned int barrier_nr; |
590 | atomic_t epoch_size; /* increased on every request added. */ | 590 | atomic_t epoch_size; /* increased on every request added. */ |
@@ -1060,7 +1060,7 @@ extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_f | |||
1060 | extern int drbd_send_state(struct drbd_conf *mdev, union drbd_state s); | 1060 | extern int drbd_send_state(struct drbd_conf *mdev, union drbd_state s); |
1061 | extern int drbd_send_current_state(struct drbd_conf *mdev); | 1061 | extern int drbd_send_current_state(struct drbd_conf *mdev); |
1062 | extern int drbd_send_sync_param(struct drbd_conf *mdev); | 1062 | extern int drbd_send_sync_param(struct drbd_conf *mdev); |
1063 | extern void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, | 1063 | extern void drbd_send_b_ack(struct drbd_tconn *tconn, u32 barrier_nr, |
1064 | u32 set_size); | 1064 | u32 set_size); |
1065 | extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet, | 1065 | extern int drbd_send_ack(struct drbd_conf *, enum drbd_packet, |
1066 | struct drbd_peer_request *); | 1066 | struct drbd_peer_request *); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 5529d392e5d3..f8438d426d06 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1463,21 +1463,21 @@ int drbd_send_bitmap(struct drbd_conf *mdev) | |||
1463 | return err; | 1463 | return err; |
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | void drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size) | 1466 | void drbd_send_b_ack(struct drbd_tconn *tconn, u32 barrier_nr, u32 set_size) |
1467 | { | 1467 | { |
1468 | struct drbd_socket *sock; | 1468 | struct drbd_socket *sock; |
1469 | struct p_barrier_ack *p; | 1469 | struct p_barrier_ack *p; |
1470 | 1470 | ||
1471 | if (mdev->state.conn < C_CONNECTED) | 1471 | if (tconn->cstate < C_WF_REPORT_PARAMS) |
1472 | return; | 1472 | return; |
1473 | 1473 | ||
1474 | sock = &mdev->tconn->meta; | 1474 | sock = &tconn->meta; |
1475 | p = drbd_prepare_command(mdev, sock); | 1475 | p = conn_prepare_command(tconn, sock); |
1476 | if (!p) | 1476 | if (!p) |
1477 | return; | 1477 | return; |
1478 | p->barrier = barrier_nr; | 1478 | p->barrier = barrier_nr; |
1479 | p->set_size = cpu_to_be32(set_size); | 1479 | p->set_size = cpu_to_be32(set_size); |
1480 | drbd_send_command(mdev, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0); | 1480 | conn_send_command(tconn, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0); |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | /** | 1483 | /** |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index b159ad15abe5..786a75510798 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1169,11 +1169,15 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_tconn *tconn, | |||
1169 | (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) || ev & EV_CLEANUP)) { | 1169 | (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) || ev & EV_CLEANUP)) { |
1170 | if (!(ev & EV_CLEANUP)) { | 1170 | if (!(ev & EV_CLEANUP)) { |
1171 | spin_unlock(&tconn->epoch_lock); | 1171 | spin_unlock(&tconn->epoch_lock); |
1172 | drbd_send_b_ack(epoch->mdev, epoch->barrier_nr, epoch_size); | 1172 | drbd_send_b_ack(epoch->tconn, epoch->barrier_nr, epoch_size); |
1173 | spin_lock(&tconn->epoch_lock); | 1173 | spin_lock(&tconn->epoch_lock); |
1174 | } | 1174 | } |
1175 | #if 0 | ||
1176 | /* FIXME: dec unacked on connection, once we have | ||
1177 | * something to count pending connection packets in. */ | ||
1175 | if (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) | 1178 | if (test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) |
1176 | dec_unacked(epoch->mdev); | 1179 | dec_unacked(epoch->tconn); |
1180 | #endif | ||
1177 | 1181 | ||
1178 | if (tconn->current_epoch != epoch) { | 1182 | if (tconn->current_epoch != epoch) { |
1179 | next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list); | 1183 | next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list); |
@@ -1369,19 +1373,15 @@ void conn_wait_active_ee_empty(struct drbd_tconn *tconn) | |||
1369 | 1373 | ||
1370 | static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) | 1374 | static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) |
1371 | { | 1375 | { |
1372 | struct drbd_conf *mdev; | ||
1373 | int rv; | 1376 | int rv; |
1374 | struct p_barrier *p = pi->data; | 1377 | struct p_barrier *p = pi->data; |
1375 | struct drbd_epoch *epoch; | 1378 | struct drbd_epoch *epoch; |
1376 | 1379 | ||
1377 | mdev = vnr_to_mdev(tconn, pi->vnr); | 1380 | /* FIXME these are unacked on connection, |
1378 | if (!mdev) | 1381 | * not a specific (peer)device. |
1379 | return -EIO; | 1382 | */ |
1380 | |||
1381 | inc_unacked(mdev); | ||
1382 | |||
1383 | tconn->current_epoch->barrier_nr = p->barrier; | 1383 | tconn->current_epoch->barrier_nr = p->barrier; |
1384 | tconn->current_epoch->mdev = mdev; | 1384 | tconn->current_epoch->tconn = tconn; |
1385 | rv = drbd_may_finish_epoch(tconn, tconn->current_epoch, EV_GOT_BARRIER_NR); | 1385 | rv = drbd_may_finish_epoch(tconn, tconn->current_epoch, EV_GOT_BARRIER_NR); |
1386 | 1386 | ||
1387 | /* P_BARRIER_ACK may imply that the corresponding extent is dropped from | 1387 | /* P_BARRIER_ACK may imply that the corresponding extent is dropped from |
@@ -1400,7 +1400,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1400 | if (epoch) | 1400 | if (epoch) |
1401 | break; | 1401 | break; |
1402 | else | 1402 | else |
1403 | dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); | 1403 | conn_warn(tconn, "Allocation of an epoch failed, slowing down\n"); |
1404 | /* Fall through */ | 1404 | /* Fall through */ |
1405 | 1405 | ||
1406 | case WO_bdev_flush: | 1406 | case WO_bdev_flush: |
@@ -1414,15 +1414,9 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1414 | break; | 1414 | break; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | epoch = tconn->current_epoch; | ||
1418 | wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0); | ||
1419 | |||
1420 | D_ASSERT(atomic_read(&epoch->active) == 0); | ||
1421 | D_ASSERT(epoch->flags == 0); | ||
1422 | |||
1423 | return 0; | 1417 | return 0; |
1424 | default: | 1418 | default: |
1425 | dev_err(DEV, "Strangeness in tconn->write_ordering %d\n", tconn->write_ordering); | 1419 | conn_err(tconn, "Strangeness in tconn->write_ordering %d\n", tconn->write_ordering); |
1426 | return -EIO; | 1420 | return -EIO; |
1427 | } | 1421 | } |
1428 | 1422 | ||
@@ -5049,21 +5043,22 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
5049 | 5043 | ||
5050 | static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) | 5044 | static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) |
5051 | { | 5045 | { |
5052 | struct drbd_conf *mdev; | ||
5053 | struct p_barrier_ack *p = pi->data; | 5046 | struct p_barrier_ack *p = pi->data; |
5047 | struct drbd_conf *mdev; | ||
5048 | int vnr; | ||
5054 | 5049 | ||
5055 | mdev = vnr_to_mdev(tconn, pi->vnr); | 5050 | tl_release(tconn, p->barrier, be32_to_cpu(p->set_size)); |
5056 | if (!mdev) | ||
5057 | return -EIO; | ||
5058 | |||
5059 | tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size)); | ||
5060 | 5051 | ||
5061 | if (mdev->state.conn == C_AHEAD && | 5052 | rcu_read_lock(); |
5062 | atomic_read(&mdev->ap_in_flight) == 0 && | 5053 | idr_for_each_entry(&tconn->volumes, mdev, vnr) { |
5063 | !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->flags)) { | 5054 | if (mdev->state.conn == C_AHEAD && |
5064 | mdev->start_resync_timer.expires = jiffies + HZ; | 5055 | atomic_read(&mdev->ap_in_flight) == 0 && |
5065 | add_timer(&mdev->start_resync_timer); | 5056 | !test_and_set_bit(AHEAD_TO_SYNC_SOURCE, &mdev->flags)) { |
5057 | mdev->start_resync_timer.expires = jiffies + HZ; | ||
5058 | add_timer(&mdev->start_resync_timer); | ||
5059 | } | ||
5066 | } | 5060 | } |
5061 | rcu_read_unlock(); | ||
5067 | 5062 | ||
5068 | return 0; | 5063 | return 0; |
5069 | } | 5064 | } |