aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-03-26 14:12:24 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:58:25 -0500
commit648e46b531006b069c66f171151819d10b423c26 (patch)
treee0550b7e6972b46bb580637c02895a6a2d87dc67 /drivers/block/drbd/drbd_req.c
parent4439c400ab278378a82efb543bb3bb91b184d8db (diff)
drbd: complete_conflicting_writes() should not care about connections
complete_conflicting_writes() should not cause -EIO. It should not timeout either, or care for connection states. Connection timeout is detected elsewhere, and it's cleanup path is supposed to remove any pending requests or peer_requests from the write_requests tree. 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_req.c')
-rw-r--r--drivers/block/drbd/drbd_req.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 1249672519ca..c76402c3f64c 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -800,21 +800,33 @@ static bool remote_due_to_read_balancing(struct drbd_conf *mdev, sector_t sector
800 * The write_requests tree contains all active write requests which we 800 * The write_requests tree contains all active write requests which we
801 * currently know about. Wait for any requests to complete which conflict with 801 * currently know about. Wait for any requests to complete which conflict with
802 * the new one. 802 * the new one.
803 *
804 * Only way out: remove the conflicting intervals from the tree.
803 */ 805 */
804static int complete_conflicting_writes(struct drbd_conf *mdev, 806static void complete_conflicting_writes(struct drbd_request *req)
805 sector_t sector, int size)
806{ 807{
807 for(;;) { 808 DEFINE_WAIT(wait);
808 struct drbd_interval *i; 809 struct drbd_conf *mdev = req->w.mdev;
809 int err; 810 struct drbd_interval *i;
811 sector_t sector = req->i.sector;
812 int size = req->i.size;
810 813
814 i = drbd_find_overlap(&mdev->write_requests, sector, size);
815 if (!i)
816 return;
817
818 for (;;) {
819 prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE);
811 i = drbd_find_overlap(&mdev->write_requests, sector, size); 820 i = drbd_find_overlap(&mdev->write_requests, sector, size);
812 if (!i) 821 if (!i)
813 return 0; 822 break;
814 err = drbd_wait_misc(mdev, i); 823 /* Indicate to wake up device->misc_wait on progress. */
815 if (err) 824 i->waiting = true;
816 return err; 825 spin_unlock_irq(&mdev->tconn->req_lock);
826 schedule();
827 spin_lock_irq(&mdev->tconn->req_lock);
817 } 828 }
829 finish_wait(&mdev->misc_wait, &wait);
818} 830}
819 831
820int __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) 832int __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
@@ -826,7 +838,7 @@ int __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long s
826 struct drbd_request *req; 838 struct drbd_request *req;
827 struct net_conf *nc; 839 struct net_conf *nc;
828 int local, remote, send_oos = 0; 840 int local, remote, send_oos = 0;
829 int err; 841 int err = 0;
830 int ret = 0; 842 int ret = 0;
831 union drbd_dev_state s; 843 union drbd_dev_state s;
832 844
@@ -925,16 +937,10 @@ allocate_barrier:
925 spin_lock_irq(&mdev->tconn->req_lock); 937 spin_lock_irq(&mdev->tconn->req_lock);
926 938
927 if (rw == WRITE) { 939 if (rw == WRITE) {
928 err = complete_conflicting_writes(mdev, sector, size); 940 /* This may temporarily give up the req_lock,
929 if (err) { 941 * but will re-aquire it before it returns here.
930 if (err != -ERESTARTSYS) 942 * Needs to be before the check on drbd_suspended() */
931 _conn_request_state(mdev->tconn, 943 complete_conflicting_writes(req);
932 NS(conn, C_TIMEOUT),
933 CS_HARD);
934 spin_unlock_irq(&mdev->tconn->req_lock);
935 err = -EIO;
936 goto fail_free_complete;
937 }
938 } 944 }
939 945
940 if (drbd_suspended(mdev)) { 946 if (drbd_suspended(mdev)) {