aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-06-14 08:21:32 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-07-24 08:06:18 -0400
commit383606e0dea6a380097dbcb0c319b09ca372f36b (patch)
tree170c3c95c12bd0a3e6cca0b7d13a4c4cc91f040e /drivers/block/drbd/drbd_main.c
parentd264580145a0aee2f5113c37b178a55b6e1b0b32 (diff)
drbd: differentiate between normal and forced detach
Aborting local requests (not waiting for completion from the lower level disk) is dangerous: if the master bio has been completed to upper layers, data pages may be re-used for other things already. If local IO is still pending and later completes, this may cause crashes or corrupt unrelated data. Only abort local IO if explicitly requested. Intended use case is a lower level device that turned into a tarpit, not completing io requests, not even doing error completion. 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.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 920ede2829d6..5bebe8d8ace3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1630,9 +1630,21 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1630 eh = mdev->ldev->dc.on_io_error; 1630 eh = mdev->ldev->dc.on_io_error;
1631 was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); 1631 was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
1632 1632
1633 /* Immediately allow completion of all application IO, that waits 1633 /* Immediately allow completion of all application IO,
1634 for completion from the local disk. */ 1634 * that waits for completion from the local disk,
1635 tl_abort_disk_io(mdev); 1635 * if this was a force-detach due to disk_timeout
1636 * or administrator request (drbdsetup detach --force).
1637 * Do NOT abort otherwise.
1638 * Aborting local requests may cause serious problems,
1639 * if requests are completed to upper layers already,
1640 * and then later the already submitted local bio completes.
1641 * This can cause DMA into former bio pages that meanwhile
1642 * have been re-used for other things.
1643 * So aborting local requests may cause crashes,
1644 * or even worse, silent data corruption.
1645 */
1646 if (test_and_clear_bit(FORCE_DETACH, &mdev->flags))
1647 tl_abort_disk_io(mdev);
1636 1648
1637 /* current state still has to be D_FAILED, 1649 /* current state still has to be D_FAILED,
1638 * there is only one way out: to D_DISKLESS, 1650 * there is only one way out: to D_DISKLESS,
@@ -3870,7 +3882,7 @@ void drbd_md_sync(struct drbd_conf *mdev)
3870 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { 3882 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
3871 /* this was a try anyways ... */ 3883 /* this was a try anyways ... */
3872 dev_err(DEV, "meta data update failed!\n"); 3884 dev_err(DEV, "meta data update failed!\n");
3873 drbd_chk_io_error(mdev, 1, true); 3885 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
3874 } 3886 }
3875 3887
3876 /* Update mdev->ldev->md.la_size_sect, 3888 /* Update mdev->ldev->md.la_size_sect,