drbd: Fix for application IO with the on-io-error=pass-on policy
authorPhilipp Reisner <philipp.reisner@linbit.com>
Wed, 2 Mar 2011 23:21:30 +0000 (00:21 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Tue, 24 May 2011 07:59:49 +0000 (09:59 +0200)
In case a write failes on the local disk, go into D_INCONSISTENT
disk state. That causes future reads of that block to be shipped
to the peer.

Read retry remote was already in place.

Actually the documentation needs to get fixed now. Since the
application is still shielded from the error. (as long as we have
only a single disk failing) The difference to detach is that
we keep the disk. And therefore might keep all the other, still
working sectors up to date.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c

index b2699bb2e5303472d5e67e72086ac517195eeab7..2c38752ca8d637034fc597ea2cbeb6a5ae371054 100644 (file)
@@ -1827,6 +1827,7 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach,
                if (!forcedetach) {
                        if (__ratelimit(&drbd_ratelimit_state))
                                dev_err(DEV, "Local IO failed in %s.\n", where);
+                       _drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_HARD, NULL);
                        break;
                }
                /* NOTE fall through to detach case if forcedetach set */
index 5b525c179f39919d6e245948a434e3248c9f329b..fd308864833f1b3ea7776c98c1320f5737042f26 100644 (file)
@@ -1565,6 +1565,10 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
                put_ldev(mdev);
        }
 
+       /* Notify peer that I had a local IO error, and did not detached.. */
+       if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT)
+               drbd_send_state(mdev);
+
        /* Disks got bigger while they were detached */
        if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
            test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) {