summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher2011-01-21 17:18:39 +0100
committerPhilipp Reisner2011-08-29 11:26:31 +0200
commitdac1389ccc273b5486f2931c64c8e1672f233727 (patch)
tree51c0c5e5886928edbc7c9b8b5afa33d95698c507 /drivers/block/drbd/drbd_req.c
parentdrbd: Use interval tree for overlapping write request detection (diff)
downloadkernel-qcow2-linux-dac1389ccc273b5486f2931c64c8e1672f233727.tar.gz
kernel-qcow2-linux-dac1389ccc273b5486f2931c64c8e1672f233727.tar.xz
kernel-qcow2-linux-dac1389ccc273b5486f2931c64c8e1672f233727.zip
drbd: Add read_requests tree
We do not do collision detection for read requests, but we still need to look up the request objects when we receive a package over the network. Using the same data structure for read and write requests results in simpler code once the tl_hash and app_reads_hash tables are removed. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r--drivers/block/drbd/drbd_req.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 593576fcf64e..d2a78c4ee919 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -260,10 +260,15 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
/* remove the request from the conflict detection
* respective block_id verification hash */
- if (!hlist_unhashed(&req->collision)) {
+ if (!drbd_interval_empty(&req->i)) {
+ struct rb_root *root;
+
hlist_del(&req->collision);
- if (!drbd_interval_empty(&req->i))
- drbd_remove_interval(&mdev->write_requests, &req->i);
+ if (rw == WRITE)
+ root = &mdev->write_requests;
+ else
+ root = &mdev->read_requests;
+ drbd_remove_interval(root, &req->i);
} else
D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
@@ -332,6 +337,7 @@ static int _req_conflicts(struct drbd_request *req)
struct hlist_head *slot;
D_ASSERT(hlist_unhashed(&req->collision));
+ D_ASSERT(drbd_interval_empty(&req->i));
if (!get_net_conf(mdev))
return 0;
@@ -493,6 +499,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
/* so we can verify the handle in the answer packet
* corresponding hlist_del is in _req_may_be_done() */
hlist_add_head(&req->collision, ar_hash_slot(mdev, req->i.sector));
+ drbd_insert_interval(&mdev->read_requests, &req->i);
set_bit(UNPLUG_REMOTE, &mdev->flags);