aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2012-02-18 19:27:53 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-05-09 09:16:38 -0400
commitb6a370ba0786b5eb09c479bffeffe7baba484ab0 (patch)
treef9c77b675c02ade44902532d9f62ea4e484de5cb /drivers/block
parentfc28845bc005995b41ae8c83c7922d088f0ad228 (diff)
drbd: Fix a potential write ordering issue on SyncTarget nodes
If a SyncTarget node gets a P_RS_DATA_REPLY before a P_DATA packet for the same sector, it simply submits these two IO requests. This is be possible because on the SyncSource node, the data of the P_RS_DATA_REPLY packet was read from disk. Immediately after that a write request from upper layers came in. The disk scheduler or even the "hardware" queues on the disk drive might reorder these writes. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_receiver.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 6b0505a3c4fc..d601501c336a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1585,6 +1585,24 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
1585 return ok; 1585 return ok;
1586} 1586}
1587 1587
1588static bool overlapping_resync_write(struct drbd_conf *mdev, struct drbd_epoch_entry *data_e)
1589{
1590
1591 struct drbd_epoch_entry *rs_e;
1592 bool rv = 0;
1593
1594 spin_lock_irq(&mdev->req_lock);
1595 list_for_each_entry(rs_e, &mdev->sync_ee, w.list) {
1596 if (overlaps(data_e->sector, data_e->size, rs_e->sector, rs_e->size)) {
1597 rv = 1;
1598 break;
1599 }
1600 }
1601 spin_unlock_irq(&mdev->req_lock);
1602
1603 return rv;
1604}
1605
1588/* Called from receive_Data. 1606/* Called from receive_Data.
1589 * Synchronize packets on sock with packets on msock. 1607 * Synchronize packets on sock with packets on msock.
1590 * 1608 *
@@ -1828,6 +1846,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
1828 list_add(&e->w.list, &mdev->active_ee); 1846 list_add(&e->w.list, &mdev->active_ee);
1829 spin_unlock_irq(&mdev->req_lock); 1847 spin_unlock_irq(&mdev->req_lock);
1830 1848
1849 if (mdev->state.conn == C_SYNC_TARGET)
1850 wait_event(mdev->ee_wait, !overlapping_resync_write(mdev, e));
1851
1831 switch (mdev->net_conf->wire_protocol) { 1852 switch (mdev->net_conf->wire_protocol) {
1832 case DRBD_PROT_C: 1853 case DRBD_PROT_C:
1833 inc_unacked(mdev); 1854 inc_unacked(mdev);