drbd: Allow to wait for the completion of an epoch entry as well

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8b4ba94..078f77b 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -70,9 +70,12 @@
 	req->mdev        = mdev;
 	req->master_bio  = bio_src;
 	req->epoch       = 0;
+
 	drbd_clear_interval(&req->i);
 	req->i.sector     = bio_src->bi_sector;
 	req->i.size      = bio_src->bi_size;
+	req->i.waiting = false;
+
 	INIT_LIST_HEAD(&req->tl_requests);
 	INIT_LIST_HEAD(&req->w.list);
 
@@ -175,10 +178,6 @@
 	    (s & RQ_NET_SENT) != 0 &&
 	    req->epoch == mdev->tconn->newest_tle->br_number)
 		queue_barrier(mdev);
-
-	/* Wake up any processes waiting for this request to complete.  */
-	if ((s & RQ_NET_DONE) && (s & RQ_COLLISION))
-		wake_up(&mdev->misc_wait);
 }
 
 void complete_master_bio(struct drbd_conf *mdev,
@@ -188,6 +187,20 @@
 	dec_ap_bio(mdev);
 }
 
+
+static void drbd_remove_request_interval(struct rb_root *root,
+					 struct drbd_request *req)
+{
+	struct drbd_conf *mdev = req->mdev;
+	struct drbd_interval *i = &req->i;
+
+	drbd_remove_interval(root, i);
+
+	/* Wake up any processes waiting for this request to complete.  */
+	if (i->waiting)
+		wake_up(&mdev->misc_wait);
+}
+
 /* Helper for __req_mod().
  * Set m->bio to the master bio, if it is fit to be completed,
  * or leave it alone (it is initialized to NULL in __req_mod),
@@ -251,7 +264,7 @@
 				root = &mdev->write_requests;
 			else
 				root = &mdev->read_requests;
-			drbd_remove_interval(root, &req->i);
+			drbd_remove_request_interval(root, req);
 		} else
 			D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);