summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorPhilipp Reisner2011-07-18 16:25:15 +0200
committerPhilipp Reisner2012-05-09 15:15:43 +0200
commitfd2491f4a4a403b376f71a336a36848158efb0fe (patch)
tree7571481867dd5ab427541a377a885f3152994fa1 /drivers/block/drbd/drbd_main.c
parentdrbd: Consider that the no-data-condition could be in connected state (diff)
downloadkernel-qcow2-linux-fd2491f4a4a403b376f71a336a36848158efb0fe.tar.gz
kernel-qcow2-linux-fd2491f4a4a403b376f71a336a36848158efb0fe.tar.xz
kernel-qcow2-linux-fd2491f4a4a403b376f71a336a36848158efb0fe.zip
drbd: detach must not try to abort non-local requests from drbd-8.4
Cherry picked form 8.4 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_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0ee05315f9ac..56569a803331 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -344,7 +344,7 @@ bail:
* @what: The action/event to perform with all request objects
*
* @what might be one of connection_lost_while_pending, resend, fail_frozen_disk_io,
- * restart_frozen_disk_io, abort_disk_io.
+ * restart_frozen_disk_io.
*/
static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
{
@@ -368,12 +368,6 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
}
tmp = b->next;
- if (what == abort_disk_io) {
- /* Only walk the TL, leave barrier objects in place */
- b = tmp;
- continue;
- }
-
if (n_writes) {
if (what == resend) {
b->n_writes = n_writes;
@@ -422,7 +416,6 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
/* Actions operating on the disk state, also want to work on
requests that got barrier acked. */
switch (what) {
- case abort_disk_io:
case fail_frozen_disk_io:
case restart_frozen_disk_io:
list_for_each_safe(le, tle, &mdev->barrier_acked_requests) {
@@ -483,6 +476,38 @@ void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
}
/**
+ * tl_abort_disk_io() - Abort disk I/O for all requests for a certain mdev in the TL
+ * @mdev: DRBD device.
+ */
+void tl_abort_disk_io(struct drbd_conf *mdev)
+{
+ struct drbd_tl_epoch *b;
+ struct list_head *le, *tle;
+ struct drbd_request *req;
+
+ spin_lock_irq(&mdev->req_lock);
+ b = mdev->oldest_tle;
+ while (b) {
+ list_for_each_safe(le, tle, &b->requests) {
+ req = list_entry(le, struct drbd_request, tl_requests);
+ if (!(req->rq_state & RQ_LOCAL_PENDING))
+ continue;
+ _req_mod(req, abort_disk_io);
+ }
+ b = b->next;
+ }
+
+ list_for_each_safe(le, tle, &mdev->barrier_acked_requests) {
+ req = list_entry(le, struct drbd_request, tl_requests);
+ if (!(req->rq_state & RQ_LOCAL_PENDING))
+ continue;
+ _req_mod(req, abort_disk_io);
+ }
+
+ spin_unlock_irq(&mdev->req_lock);
+}
+
+/**
* cl_wide_st_chg() - true if the state change is a cluster wide one
* @mdev: DRBD device.
* @os: old (current) state.
@@ -1577,7 +1602,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
/* Immediately allow completion of all application IO, that waits
for completion from the local disk. */
- tl_restart(mdev, abort_disk_io);
+ tl_abort_disk_io(mdev);
/* current state still has to be D_FAILED,
* there is only one way out: to D_DISKLESS,