diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-01-21 12:00:55 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-08-29 05:26:50 -0400 |
commit | bc9c5c41181a84ad243639c79a10f621a97af44b (patch) | |
tree | b4caa79173624199cae5ec5c6f6dbc7385dfbe10 /drivers/block | |
parent | dac1389ccc273b5486f2931c64c8e1672f233727 (diff) |
drbd: Use the read and write request trees for request lookups
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_interval.h | 3 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 44 |
2 files changed, 17 insertions, 30 deletions
diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h index bf8dcf7bab09..a847b4a07b25 100644 --- a/drivers/block/drbd/drbd_interval.h +++ b/drivers/block/drbd/drbd_interval.h | |||
@@ -22,8 +22,7 @@ static inline bool drbd_interval_empty(struct drbd_interval *i) | |||
22 | } | 22 | } |
23 | 23 | ||
24 | bool drbd_insert_interval(struct rb_root *, struct drbd_interval *); | 24 | bool drbd_insert_interval(struct rb_root *, struct drbd_interval *); |
25 | struct drbd_interval *drbd_find_interval(struct rb_root *, sector_t, | 25 | bool drbd_contains_interval(struct rb_root *, sector_t, struct drbd_interval *); |
26 | struct drbd_interval *); | ||
27 | void drbd_remove_interval(struct rb_root *, struct drbd_interval *); | 26 | void drbd_remove_interval(struct rb_root *, struct drbd_interval *); |
28 | struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t, | 27 | struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t, |
29 | unsigned int); | 28 | unsigned int); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6b0725842508..b148398b5aa4 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1470,27 +1470,15 @@ fail: | |||
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | static struct drbd_request * | 1472 | static struct drbd_request * |
1473 | find_request(struct drbd_conf *mdev, | 1473 | find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id, |
1474 | struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t), | 1474 | sector_t sector, bool missing_ok, const char *func) |
1475 | u64 id, sector_t sector, bool missing_ok, const char *func) | ||
1476 | { | 1475 | { |
1477 | struct hlist_head *slot = hash_slot(mdev, sector); | ||
1478 | struct hlist_node *n; | ||
1479 | struct drbd_request *req; | 1476 | struct drbd_request *req; |
1480 | 1477 | ||
1481 | hlist_for_each_entry(req, n, slot, collision) { | 1478 | /* Request object according to our peer */ |
1482 | if ((unsigned long)req != (unsigned long)id) | 1479 | req = (struct drbd_request *)(unsigned long)id; |
1483 | continue; | 1480 | if (drbd_contains_interval(root, sector, &req->i)) |
1484 | if (req->i.sector != sector) { | ||
1485 | dev_err(DEV, "%s: found request %lu but it has " | ||
1486 | "wrong sector (%llus versus %llus)\n", | ||
1487 | func, (unsigned long)req, | ||
1488 | (unsigned long long)req->i.sector, | ||
1489 | (unsigned long long)sector); | ||
1490 | return NULL; | ||
1491 | } | ||
1492 | return req; | 1481 | return req; |
1493 | } | ||
1494 | if (!missing_ok) { | 1482 | if (!missing_ok) { |
1495 | dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func, | 1483 | dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func, |
1496 | (unsigned long)id, (unsigned long long)sector); | 1484 | (unsigned long)id, (unsigned long long)sector); |
@@ -1508,7 +1496,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi | |||
1508 | sector = be64_to_cpu(p->sector); | 1496 | sector = be64_to_cpu(p->sector); |
1509 | 1497 | ||
1510 | spin_lock_irq(&mdev->req_lock); | 1498 | spin_lock_irq(&mdev->req_lock); |
1511 | req = find_request(mdev, ar_hash_slot, p->block_id, sector, false, __func__); | 1499 | req = find_request(mdev, &mdev->read_requests, p->block_id, sector, false, __func__); |
1512 | spin_unlock_irq(&mdev->req_lock); | 1500 | spin_unlock_irq(&mdev->req_lock); |
1513 | if (unlikely(!req)) | 1501 | if (unlikely(!req)) |
1514 | return false; | 1502 | return false; |
@@ -4245,16 +4233,16 @@ static int got_IsInSync(struct drbd_conf *mdev, struct p_header80 *h) | |||
4245 | return true; | 4233 | return true; |
4246 | } | 4234 | } |
4247 | 4235 | ||
4248 | static int validate_req_change_req_state(struct drbd_conf *mdev, | 4236 | static int |
4249 | u64 id, sector_t sector, | 4237 | validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector, |
4250 | struct hlist_head *(*hash_slot)(struct drbd_conf *, sector_t), | 4238 | struct rb_root *root, const char *func, |
4251 | const char *func, enum drbd_req_event what, bool missing_ok) | 4239 | enum drbd_req_event what, bool missing_ok) |
4252 | { | 4240 | { |
4253 | struct drbd_request *req; | 4241 | struct drbd_request *req; |
4254 | struct bio_and_error m; | 4242 | struct bio_and_error m; |
4255 | 4243 | ||
4256 | spin_lock_irq(&mdev->req_lock); | 4244 | spin_lock_irq(&mdev->req_lock); |
4257 | req = find_request(mdev, hash_slot, id, sector, missing_ok, func); | 4245 | req = find_request(mdev, root, id, sector, missing_ok, func); |
4258 | if (unlikely(!req)) { | 4246 | if (unlikely(!req)) { |
4259 | spin_unlock_irq(&mdev->req_lock); | 4247 | spin_unlock_irq(&mdev->req_lock); |
4260 | return false; | 4248 | return false; |
@@ -4304,8 +4292,8 @@ static int got_BlockAck(struct drbd_conf *mdev, struct p_header80 *h) | |||
4304 | } | 4292 | } |
4305 | 4293 | ||
4306 | return validate_req_change_req_state(mdev, p->block_id, sector, | 4294 | return validate_req_change_req_state(mdev, p->block_id, sector, |
4307 | tl_hash_slot, __func__, what, | 4295 | &mdev->write_requests, __func__, |
4308 | false); | 4296 | what, false); |
4309 | } | 4297 | } |
4310 | 4298 | ||
4311 | static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h) | 4299 | static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h) |
@@ -4326,7 +4314,7 @@ static int got_NegAck(struct drbd_conf *mdev, struct p_header80 *h) | |||
4326 | } | 4314 | } |
4327 | 4315 | ||
4328 | found = validate_req_change_req_state(mdev, p->block_id, sector, | 4316 | found = validate_req_change_req_state(mdev, p->block_id, sector, |
4329 | tl_hash_slot, __func__, | 4317 | &mdev->write_requests, __func__, |
4330 | neg_acked, missing_ok); | 4318 | neg_acked, missing_ok); |
4331 | if (!found) { | 4319 | if (!found) { |
4332 | /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs. | 4320 | /* Protocol A has no P_WRITE_ACKs, but has P_NEG_ACKs. |
@@ -4351,8 +4339,8 @@ static int got_NegDReply(struct drbd_conf *mdev, struct p_header80 *h) | |||
4351 | (unsigned long long)sector, be32_to_cpu(p->blksize)); | 4339 | (unsigned long long)sector, be32_to_cpu(p->blksize)); |
4352 | 4340 | ||
4353 | return validate_req_change_req_state(mdev, p->block_id, sector, | 4341 | return validate_req_change_req_state(mdev, p->block_id, sector, |
4354 | ar_hash_slot, __func__, neg_acked, | 4342 | &mdev->read_requests, __func__, |
4355 | false); | 4343 | neg_acked, false); |
4356 | } | 4344 | } |
4357 | 4345 | ||
4358 | static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h) | 4346 | static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header80 *h) |