Commit b6a370ba authored by Philipp Reisner's avatar Philipp Reisner

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent fc28845b
......@@ -1585,6 +1585,24 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
return ok;
}
static bool overlapping_resync_write(struct drbd_conf *mdev, struct drbd_epoch_entry *data_e)
{
struct drbd_epoch_entry *rs_e;
bool rv = 0;
spin_lock_irq(&mdev->req_lock);
list_for_each_entry(rs_e, &mdev->sync_ee, w.list) {
if (overlaps(data_e->sector, data_e->size, rs_e->sector, rs_e->size)) {
rv = 1;
break;
}
}
spin_unlock_irq(&mdev->req_lock);
return rv;
}
/* Called from receive_Data.
* Synchronize packets on sock with packets on msock.
*
......@@ -1828,6 +1846,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
list_add(&e->w.list, &mdev->active_ee);
spin_unlock_irq(&mdev->req_lock);
if (mdev->state.conn == C_SYNC_TARGET)
wait_event(mdev->ee_wait, !overlapping_resync_write(mdev, e));
switch (mdev->net_conf->wire_protocol) {
case DRBD_PROT_C:
inc_unacked(mdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment