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 || /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs.
mdev->net_conf->wire_protocol == DRBD_PROT_B) { The master bio might already be completed, therefore the
/* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs. request is no longer in the collision hash. */
The master bio might already be completed, therefore the /* In Protocol B we might already have got a P_RECV_ACK
request is no longer in the collision hash. but then get a P_NEG_ACK afterwards. */
=> Do not try to validate block_id as request. */ if (!missing_ok)
/* In Protocol B we might already have got a P_RECV_ACK
but then get a P_NEG_ACK after wards. */
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);
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