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

Commit 8d6cdd78 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner
Browse files

drbd: conflicting writes: make wake_up of waiting peer_requests explicit

parent 0afd569a
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -212,6 +212,16 @@ static void drbd_remove_request_interval(struct rb_root *root,
		wake_up(&mdev->misc_wait);
}

static void maybe_wakeup_conflicting_requests(struct drbd_request *req)
{
	const unsigned long s = req->rq_state;
	if (s & RQ_LOCAL_PENDING && !(s & RQ_LOCAL_ABORTED))
		return;
	if (req->i.waiting)
		/* Retry all conflicting peer requests.  */
		wake_up(&req->w.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),
@@ -235,10 +245,6 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
	 */
	if (s & RQ_LOCAL_PENDING && !(s & RQ_LOCAL_ABORTED))
		return;
	if (req->i.waiting) {
		/* Retry all conflicting peer requests.  */
		wake_up(&mdev->misc_wait);
	}
	if (s & RQ_NET_QUEUED)
		return;
	if (s & RQ_NET_PENDING)
@@ -388,6 +394,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK);
		req->rq_state &= ~RQ_LOCAL_PENDING;

		maybe_wakeup_conflicting_requests(req);
		_req_may_be_done_not_susp(req, m);
		put_ldev(mdev);
		break;
@@ -405,6 +412,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		req->rq_state &= ~RQ_LOCAL_PENDING;

		__drbd_chk_io_error(mdev, false);
		maybe_wakeup_conflicting_requests(req);
		_req_may_be_done_not_susp(req, m);
		put_ldev(mdev);
		break;
@@ -615,6 +623,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		dec_ap_pending(mdev);
		atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
		req->rq_state &= ~RQ_NET_PENDING;
		maybe_wakeup_conflicting_requests(req);
		_req_may_be_done_not_susp(req, m);
		break;

@@ -626,6 +635,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		 */
		D_ASSERT(req->rq_state & RQ_NET_PENDING);
		req->rq_state |= RQ_POSTPONED;
		maybe_wakeup_conflicting_requests(req);
		_req_may_be_done_not_susp(req, m);
		break;

@@ -643,6 +653,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		if (!(req->rq_state & RQ_WRITE))
			goto goto_read_retry_local;

		maybe_wakeup_conflicting_requests(req);
		_req_may_be_done_not_susp(req, m);
		/* else: done by HANDED_OVER_TO_NETWORK */
		break;