drbd: Request lookup code cleanup (4)
Factor out duplicate code in got_NegAck(). Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
Родитель
ae3388daae
Коммит
c3afd8f568
|
@ -1472,7 +1472,7 @@ fail:
|
|||
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 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);
|
||||
but then get a P_NEG_ACK afterwards. */
|
||||
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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче