Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 648e46b5 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner
Browse files

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 4439c400
Loading
Loading
Loading
Loading
+26 −20
Original line number Diff line number Diff line
@@ -800,21 +800,33 @@ static bool remote_due_to_read_balancing(struct drbd_conf *mdev, sector_t sector
 * The write_requests tree contains all active write requests which we
 * currently know about.  Wait for any requests to complete which conflict with
 * the new one.
 *
 * Only way out: remove the conflicting intervals from the tree.
 */
static int complete_conflicting_writes(struct drbd_conf *mdev,
				       sector_t sector, int size)
static void complete_conflicting_writes(struct drbd_request *req)
{
	for(;;) {
	DEFINE_WAIT(wait);
	struct drbd_conf *mdev = req->w.mdev;
	struct drbd_interval *i;
		int err;
	sector_t sector = req->i.sector;
	int size = req->i.size;

	i = drbd_find_overlap(&mdev->write_requests, sector, size);
	if (!i)
			return 0;
		err = drbd_wait_misc(mdev, i);
		if (err)
			return err;
		return;

	for (;;) {
		prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE);
		i = drbd_find_overlap(&mdev->write_requests, sector, size);
		if (!i)
			break;
		/* Indicate to wake up device->misc_wait on progress.  */
		i->waiting = true;
		spin_unlock_irq(&mdev->tconn->req_lock);
		schedule();
		spin_lock_irq(&mdev->tconn->req_lock);
	}
	finish_wait(&mdev->misc_wait, &wait);
}

int __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
	struct drbd_request *req;
	struct net_conf *nc;
	int local, remote, send_oos = 0;
	int err;
	int err = 0;
	int ret = 0;
	union drbd_dev_state s;

@@ -925,16 +937,10 @@ int __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long s
	spin_lock_irq(&mdev->tconn->req_lock);

	if (rw == WRITE) {
		err = complete_conflicting_writes(mdev, sector, size);
		if (err) {
			if (err != -ERESTARTSYS)
				_conn_request_state(mdev->tconn,
						    NS(conn, C_TIMEOUT),
						    CS_HARD);
			spin_unlock_irq(&mdev->tconn->req_lock);
			err = -EIO;
			goto fail_free_complete;
		}
		/* This may temporarily give up the req_lock,
		 * but will re-aquire it before it returns here.
		 * Needs to be before the check on drbd_suspended() */
		complete_conflicting_writes(req);
	}

	if (drbd_suspended(mdev)) {