summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_receiver.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher2011-01-27 14:42:51 +0100
committerPhilipp Reisner2011-09-28 10:26:32 +0200
commit5e4722645afb27ee749ea65988544450f08f78ba (patch)
tree971a99c34a30e56a8406f86aa2b9f48a08504082 /drivers/block/drbd/drbd_receiver.c
parentdrbd: Allow to wait for the completion of an epoch entry as well (diff)
downloadkernel-qcow2-linux-5e4722645afb27ee749ea65988544450f08f78ba.tar.gz
kernel-qcow2-linux-5e4722645afb27ee749ea65988544450f08f78ba.tar.xz
kernel-qcow2-linux-5e4722645afb27ee749ea65988544450f08f78ba.zip
drbd: _req_conflicts(): Get rid of the epoch_entries tree
Instead of keeping a separate tree for local and remote write requests for finding requests and for conflict detection, use the same tree for both purposes. Introduce a flag to allow distinguishing the two possible types of entries in this tree. 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_receiver.c')
-rw-r--r--drivers/block/drbd/drbd_receiver.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index b84a9c9fd3f8..b063ca234462 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -336,6 +336,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
drbd_clear_interval(&e->i);
e->i.size = data_size;
e->i.sector = sector;
+ e->i.local = false;
e->i.waiting = false;
e->epoch = NULL;
@@ -1508,7 +1509,7 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
/* Request object according to our peer */
req = (struct drbd_request *)(unsigned long)id;
- if (drbd_contains_interval(root, sector, &req->i))
+ if (drbd_contains_interval(root, sector, &req->i) && req->i.local)
return req;
if (!missing_ok) {
dev_err(DEV, "%s: failed to find request %lu, sector %llus\n", func,
@@ -1788,17 +1789,12 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
/* conflict detection and handling:
* 1. wait on the sequence number,
* in case this data packet overtook ACK packets.
- * 2. check our interval trees for conflicting requests:
- * we only need to check the write_requests tree; the
- * epoch_entries tree cannot contain any overlaps because
- * they were already eliminated on the submitting node.
+ * 2. check for conflicting write requests.
*
* Note: for two_primaries, we are protocol C,
* so there cannot be any request that is DONE
* but still on the transfer log.
*
- * unconditionally add to the epoch_entries tree.
- *
* if no conflicting request is found:
* submit.
*
@@ -1823,12 +1819,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
spin_lock_irq(&mdev->tconn->req_lock);
- drbd_insert_interval(&mdev->epoch_entries, &e->i);
-
first = 1;
for (;;) {
struct drbd_interval *i;
- struct drbd_request *req2;
int have_unacked = 0;
int have_conflict = 0;
prepare_to_wait(&mdev->misc_wait, &wait,
@@ -1836,18 +1829,23 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
i = drbd_find_overlap(&mdev->write_requests, sector, size);
if (i) {
- req2 = container_of(i, struct drbd_request, i);
-
/* only ALERT on first iteration,
* we may be woken up early... */
if (first)
- dev_alert(DEV, "%s[%u] Concurrent local write detected!"
+ dev_alert(DEV, "%s[%u] Concurrent %s write detected!"
" new: %llus +%u; pending: %llus +%u\n",
current->comm, current->pid,
+ i->local ? "local" : "remote",
(unsigned long long)sector, size,
- (unsigned long long)req2->i.sector, req2->i.size);
- if (req2->rq_state & RQ_NET_PENDING)
- ++have_unacked;
+ (unsigned long long)i->sector, i->size);
+
+ if (i->local) {
+ struct drbd_request *req2;
+
+ req2 = container_of(i, struct drbd_request, i);
+ if (req2->rq_state & RQ_NET_PENDING)
+ ++have_unacked;
+ }
++have_conflict;
}
if (!have_conflict)
@@ -1873,7 +1871,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
}
if (signal_pending(current)) {
- drbd_remove_epoch_entry_interval(mdev, e);
spin_unlock_irq(&mdev->tconn->req_lock);
finish_wait(&mdev->misc_wait, &wait);
goto out_interrupted;
@@ -1896,6 +1893,8 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
spin_lock_irq(&mdev->tconn->req_lock);
}
finish_wait(&mdev->misc_wait, &wait);
+
+ drbd_insert_interval(&mdev->write_requests, &e->i);
}
list_add(&e->w.list, &mdev->active_ee);