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

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
...@@ -1472,7 +1472,7 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si ...@@ -1472,7 +1472,7 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
static struct drbd_request * static struct drbd_request *
find_request(struct drbd_conf *mdev, find_request(struct drbd_conf *mdev,
struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t), 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_head *slot = hash_slot(mdev, sector);
struct hlist_node *n; struct hlist_node *n;
...@@ -1487,10 +1487,14 @@ find_request(struct drbd_conf *mdev, ...@@ -1487,10 +1487,14 @@ find_request(struct drbd_conf *mdev,
func, (unsigned long)req, func, (unsigned long)req,
(unsigned long long)req->sector, (unsigned long long)req->sector,
(unsigned long long)sector); (unsigned long long)sector);
break; return NULL;
} }
return req; 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; return NULL;
} }
...@@ -1504,12 +1508,10 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi ...@@ -1504,12 +1508,10 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
spin_lock_irq(&mdev->req_lock); 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); spin_unlock_irq(&mdev->req_lock);
if (unlikely(!req)) { if (unlikely(!req))
dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
return false; return false;
}
/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
* special casing it there for the various failure cases. * 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) ...@@ -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, static int validate_req_change_req_state(struct drbd_conf *mdev,
u64 id, sector_t sector, u64 id, sector_t sector,
struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t), 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 drbd_request *req;
struct bio_and_error m; struct bio_and_error m;
spin_lock_irq(&mdev->req_lock); 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)) { if (unlikely(!req)) {
spin_unlock_irq(&mdev->req_lock); 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; return false;
} }
__req_mod(req, what, &m); __req_mod(req, what, &m);
...@@ -4307,7 +4306,8 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h) ...@@ -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, 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) 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) ...@@ -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; struct p_block_ack *p = (struct p_block_ack *)h;
sector_t sector = be64_to_cpu(p->sector); sector_t sector = be64_to_cpu(p->sector);
int size = be32_to_cpu(p->blksize); int size = be32_to_cpu(p->blksize);
struct drbd_request *req; bool missing_ok = mdev->net_conf->wire_protocol == DRBD_PROT_A ||
struct bio_and_error m; mdev->net_conf->wire_protocol == DRBD_PROT_B;
bool found;
update_peer_seq(mdev, be32_to_cpu(p->seq_num)); 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) ...@@ -4326,31 +4327,19 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h)
return true; return true;
} }
spin_lock_irq(&mdev->req_lock); found = validate_req_change_req_state(mdev, p->block_id, sector,
req = find_request(mdev, tl_hash_slot, p->block_id, sector, __func__); tl_hash_slot, __func__,
if (!req) { neg_acked, missing_ok);
spin_unlock_irq(&mdev->req_lock); if (!found) {
if (mdev->net_conf->wire_protocol == DRBD_PROT_A ||
mdev->net_conf->wire_protocol == DRBD_PROT_B) {
/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs. /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
The master bio might already be completed, therefore the The master bio might already be completed, therefore the
request is no longer in the collision hash. request is no longer in the collision hash. */
=> Do not try to validate block_id as request. */
/* In Protocol B we might already have got a P_RECV_ACK /* In Protocol B we might already have got a P_RECV_ACK
but then get a P_NEG_ACK after wards. */ but then get a P_NEG_ACK afterwards. */
drbd_set_out_of_sync(mdev, sector, size); if (!missing_ok)
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);
return false; 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; return true;
} }
...@@ -4364,7 +4353,8 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h) ...@@ -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)); (unsigned long long)sector, be32_to_cpu(p->blksize));
return validate_req_change_req_state(mdev, p->block_id, sector, 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) static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment