Commit c3afd8f5 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner
Browse files

drbd: Request lookup code cleanup (4)



Factor out duplicate code in got_NegAck().

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent ae3388da
Loading
Loading
Loading
Loading
+28 −38
Original line number Diff line number Diff line
@@ -1472,7 +1472,7 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
static struct drbd_request *
find_request(struct drbd_conf *mdev,
	     struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
	     u64 id, sector_t sector, const char *func)
	     u64 id, sector_t sector, bool missing_ok, const char *func)
{
	struct hlist_head *slot = hash_slot(mdev, sector);
	struct hlist_node *n;
@@ -1487,10 +1487,14 @@ find_request(struct drbd_conf *mdev,
				func, (unsigned long)req,
				(unsigned long long)req->sector,
				(unsigned long long)sector);
			break;
			return NULL;
		}
		return req;
	}
	if (!missing_ok) {
		dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func,
			(unsigned long)id, (unsigned long long)sector);
	}
	return NULL;
}

@@ -1504,12 +1508,10 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
	sector = be64_to_cpu(p->sector);

	spin_lock_irq(&mdev->req_lock);
	req = find_request(mdev, ar_hash_slot, p->block_id, sector, __func__);
	req = find_request(mdev, ar_hash_slot, p->block_id, sector, false, __func__);
	spin_unlock_irq(&mdev->req_lock);
	if (unlikely(!req)) {
		dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
	if (unlikely(!req))
		return false;
	}

	/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
	 * special casing it there for the various failure cases.
@@ -4248,18 +4250,15 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h)
static int validate_req_change_req_state(struct drbd_conf *mdev,
	u64 id, sector_t sector,
	struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t),
	const char *func, enum drbd_req_event what)
	const char *func, enum drbd_req_event what, bool missing_ok)
{
	struct drbd_request *req;
	struct bio_and_error m;

	spin_lock_irq(&mdev->req_lock);
	req = find_request(mdev, hash_slot, id, sector, func);
	req = find_request(mdev, hash_slot, id, sector, missing_ok, func);
	if (unlikely(!req)) {
		spin_unlock_irq(&mdev->req_lock);

		dev_err(DEV, "%s: failed to find req %p, sector %llus\n", func,
			(void *)(unsigned long)id, (unsigned long long)sector);
		return false;
	}
	__req_mod(req, what, &m);
@@ -4307,7 +4306,8 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h)
	}

	return validate_req_change_req_state(mdev, p->block_id, sector,
					     tl_hash_slot, __func__, what);
					     tl_hash_slot, __func__, what,
					     false);
}

static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
@@ -4315,8 +4315,9 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
	struct p_block_ack *p = (struct p_block_ack *)h;
	sector_t sector = be64_to_cpu(p->sector);
	int size = be32_to_cpu(p->blksize);
	struct drbd_request *req;
	struct bio_and_error m;
	bool missing_ok = mdev->net_conf->wire_protocol == DRBD_PROT_A ||
			  mdev->net_conf->wire_protocol == DRBD_PROT_B;
	bool found;

	update_peer_seq(mdev, be32_to_cpu(p->seq_num));

@@ -4326,31 +4327,19 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
		return true;
	}

	spin_lock_irq(&mdev->req_lock);
	req = find_request(mdev, tl_hash_slot, p->block_id, sector, __func__);
	if (!req) {
		spin_unlock_irq(&mdev->req_lock);
		if (mdev->net_conf->wire_protocol == DRBD_PROT_A ||
		    mdev->net_conf->wire_protocol == DRBD_PROT_B) {
	found = validate_req_change_req_state(mdev, p->block_id, sector,
					      tl_hash_slot, __func__,
					      neg_acked, missing_ok);
	if (!found) {
		/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
		   The master bio might already be completed, therefore the
			   request is no longer in the collision hash.
			   => Do not try to validate block_id as request. */
		   request is no longer in the collision hash. */
		/* In Protocol B we might already have got a P_RECV_ACK
		   but then get a P_NEG_ACK afterwards. */
			drbd_set_out_of_sync(mdev, sector, size);
			return true;
		} else {
			dev_err(DEV, "%s: failed to find req %p, sector %llus\n", __func__,
				(void *)(unsigned long)p->block_id, (unsigned long long)sector);
		if (!missing_ok)
			return false;
		drbd_set_out_of_sync(mdev, sector, size);
	}
	}
	__req_mod(req, neg_acked, &m);
	spin_unlock_irq(&mdev->req_lock);

	if (m.bio)
		complete_master_bio(mdev, &m);
	return true;
}

@@ -4364,7 +4353,8 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h)
	    (unsigned long long)sector, be32_to_cpu(p->blksize));

	return validate_req_change_req_state(mdev, p->block_id, sector,
					     ar_hash_slot, __func__, neg_acked);
					     ar_hash_slot, __func__, neg_acked,
					     false);
}

static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)