diff options
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 148 |
1 files changed, 85 insertions, 63 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 25c7a73c5062..6be5401d0e88 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -835,6 +835,15 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state | |||
835 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) | 835 | ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) |
836 | ns.conn = os.conn; | 836 | ns.conn = os.conn; |
837 | 837 | ||
838 | /* we cannot fail (again) if we already detached */ | ||
839 | if (ns.disk == D_FAILED && os.disk == D_DISKLESS) | ||
840 | ns.disk = D_DISKLESS; | ||
841 | |||
842 | /* if we are only D_ATTACHING yet, | ||
843 | * we can (and should) go directly to D_DISKLESS. */ | ||
844 | if (ns.disk == D_FAILED && os.disk == D_ATTACHING) | ||
845 | ns.disk = D_DISKLESS; | ||
846 | |||
838 | /* After C_DISCONNECTING only C_STANDALONE may follow */ | 847 | /* After C_DISCONNECTING only C_STANDALONE may follow */ |
839 | if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) | 848 | if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) |
840 | ns.conn = os.conn; | 849 | ns.conn = os.conn; |
@@ -1056,7 +1065,15 @@ int __drbd_set_state(struct drbd_conf *mdev, | |||
1056 | !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) | 1065 | !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) |
1057 | set_bit(DEVICE_DYING, &mdev->flags); | 1066 | set_bit(DEVICE_DYING, &mdev->flags); |
1058 | 1067 | ||
1059 | mdev->state.i = ns.i; | 1068 | /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference |
1069 | * on the ldev here, to be sure the transition -> D_DISKLESS resp. | ||
1070 | * drbd_ldev_destroy() won't happen before our corresponding | ||
1071 | * after_state_ch works run, where we put_ldev again. */ | ||
1072 | if ((os.disk != D_FAILED && ns.disk == D_FAILED) || | ||
1073 | (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) | ||
1074 | atomic_inc(&mdev->local_cnt); | ||
1075 | |||
1076 | mdev->state = ns; | ||
1060 | wake_up(&mdev->misc_wait); | 1077 | wake_up(&mdev->misc_wait); |
1061 | wake_up(&mdev->state_wait); | 1078 | wake_up(&mdev->state_wait); |
1062 | 1079 | ||
@@ -1268,7 +1285,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1268 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { | 1285 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { |
1269 | drbd_uuid_new_current(mdev); | 1286 | drbd_uuid_new_current(mdev); |
1270 | clear_bit(NEW_CUR_UUID, &mdev->flags); | 1287 | clear_bit(NEW_CUR_UUID, &mdev->flags); |
1271 | drbd_md_sync(mdev); | ||
1272 | } | 1288 | } |
1273 | spin_lock_irq(&mdev->req_lock); | 1289 | spin_lock_irq(&mdev->req_lock); |
1274 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); | 1290 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); |
@@ -1365,63 +1381,64 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1365 | os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) | 1381 | os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) |
1366 | drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); | 1382 | drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); |
1367 | 1383 | ||
1368 | /* first half of local IO error */ | 1384 | /* first half of local IO error, failure to attach, |
1369 | if (os.disk > D_FAILED && ns.disk == D_FAILED) { | 1385 | * or administrative detach */ |
1370 | enum drbd_io_error_p eh = EP_PASS_ON; | 1386 | if (os.disk != D_FAILED && ns.disk == D_FAILED) { |
1387 | enum drbd_io_error_p eh; | ||
1388 | int was_io_error; | ||
1389 | /* corresponding get_ldev was in __drbd_set_state, to serialize | ||
1390 | * our cleanup here with the transition to D_DISKLESS, | ||
1391 | * so it is safe to dreference ldev here. */ | ||
1392 | eh = mdev->ldev->dc.on_io_error; | ||
1393 | was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); | ||
1394 | |||
1395 | /* current state still has to be D_FAILED, | ||
1396 | * there is only one way out: to D_DISKLESS, | ||
1397 | * and that may only happen after our put_ldev below. */ | ||
1398 | if (mdev->state.disk != D_FAILED) | ||
1399 | dev_err(DEV, | ||
1400 | "ASSERT FAILED: disk is %s during detach\n", | ||
1401 | drbd_disk_str(mdev->state.disk)); | ||
1371 | 1402 | ||
1372 | if (drbd_send_state(mdev)) | 1403 | if (drbd_send_state(mdev)) |
1373 | dev_warn(DEV, "Notified peer that my disk is broken.\n"); | 1404 | dev_warn(DEV, "Notified peer that I am detaching my disk\n"); |
1374 | else | 1405 | else |
1375 | dev_err(DEV, "Sending state for drbd_io_error() failed\n"); | 1406 | dev_err(DEV, "Sending state for detaching disk failed\n"); |
1376 | 1407 | ||
1377 | drbd_rs_cancel_all(mdev); | 1408 | drbd_rs_cancel_all(mdev); |
1378 | 1409 | ||
1379 | if (get_ldev_if_state(mdev, D_FAILED)) { | 1410 | /* In case we want to get something to stable storage still, |
1380 | eh = mdev->ldev->dc.on_io_error; | 1411 | * this may be the last chance. |
1381 | put_ldev(mdev); | 1412 | * Following put_ldev may transition to D_DISKLESS. */ |
1382 | } | 1413 | drbd_md_sync(mdev); |
1383 | if (eh == EP_CALL_HELPER) | 1414 | put_ldev(mdev); |
1415 | |||
1416 | if (was_io_error && eh == EP_CALL_HELPER) | ||
1384 | drbd_khelper(mdev, "local-io-error"); | 1417 | drbd_khelper(mdev, "local-io-error"); |
1385 | } | 1418 | } |
1386 | 1419 | ||
1420 | /* second half of local IO error, failure to attach, | ||
1421 | * or administrative detach, | ||
1422 | * after local_cnt references have reached zero again */ | ||
1423 | if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) { | ||
1424 | /* We must still be diskless, | ||
1425 | * re-attach has to be serialized with this! */ | ||
1426 | if (mdev->state.disk != D_DISKLESS) | ||
1427 | dev_err(DEV, | ||
1428 | "ASSERT FAILED: disk is %s while going diskless\n", | ||
1429 | drbd_disk_str(mdev->state.disk)); | ||
1387 | 1430 | ||
1388 | /* second half of local IO error handling, | 1431 | mdev->rs_total = 0; |
1389 | * after local_cnt references have reached zero: */ | 1432 | mdev->rs_failed = 0; |
1390 | if (os.disk == D_FAILED && ns.disk == D_DISKLESS) { | 1433 | atomic_set(&mdev->rs_pending_cnt, 0); |
1391 | mdev->rs_total = 0; | ||
1392 | mdev->rs_failed = 0; | ||
1393 | atomic_set(&mdev->rs_pending_cnt, 0); | ||
1394 | } | ||
1395 | |||
1396 | if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) { | ||
1397 | /* We must still be diskless, | ||
1398 | * re-attach has to be serialized with this! */ | ||
1399 | if (mdev->state.disk != D_DISKLESS) | ||
1400 | dev_err(DEV, | ||
1401 | "ASSERT FAILED: disk is %s while going diskless\n", | ||
1402 | drbd_disk_str(mdev->state.disk)); | ||
1403 | 1434 | ||
1404 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state | ||
1405 | * will inc/dec it frequently. Since we became D_DISKLESS, no | ||
1406 | * one has touched the protected members anymore, though, so we | ||
1407 | * are safe to free them here. */ | ||
1408 | if (drbd_send_state(mdev)) | 1435 | if (drbd_send_state(mdev)) |
1409 | dev_warn(DEV, "Notified peer that I detached my disk.\n"); | 1436 | dev_warn(DEV, "Notified peer that I'm now diskless.\n"); |
1410 | else | 1437 | else |
1411 | dev_err(DEV, "Sending state for detach failed\n"); | 1438 | dev_err(DEV, "Sending state for being diskless failed\n"); |
1412 | 1439 | /* corresponding get_ldev in __drbd_set_state | |
1413 | lc_destroy(mdev->resync); | 1440 | * this may finaly trigger drbd_ldev_destroy. */ |
1414 | mdev->resync = NULL; | 1441 | put_ldev(mdev); |
1415 | lc_destroy(mdev->act_log); | ||
1416 | mdev->act_log = NULL; | ||
1417 | __no_warn(local, | ||
1418 | drbd_free_bc(mdev->ldev); | ||
1419 | mdev->ldev = NULL;); | ||
1420 | |||
1421 | if (mdev->md_io_tmpp) { | ||
1422 | __free_page(mdev->md_io_tmpp); | ||
1423 | mdev->md_io_tmpp = NULL; | ||
1424 | } | ||
1425 | } | 1442 | } |
1426 | 1443 | ||
1427 | /* Disks got bigger while they were detached */ | 1444 | /* Disks got bigger while they were detached */ |
@@ -2772,11 +2789,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2772 | 2789 | ||
2773 | drbd_set_defaults(mdev); | 2790 | drbd_set_defaults(mdev); |
2774 | 2791 | ||
2775 | /* for now, we do NOT yet support it, | ||
2776 | * even though we start some framework | ||
2777 | * to eventually support barriers */ | ||
2778 | set_bit(NO_BARRIER_SUPP, &mdev->flags); | ||
2779 | |||
2780 | atomic_set(&mdev->ap_bio_cnt, 0); | 2792 | atomic_set(&mdev->ap_bio_cnt, 0); |
2781 | atomic_set(&mdev->ap_pending_cnt, 0); | 2793 | atomic_set(&mdev->ap_pending_cnt, 0); |
2782 | atomic_set(&mdev->rs_pending_cnt, 0); | 2794 | atomic_set(&mdev->rs_pending_cnt, 0); |
@@ -2842,7 +2854,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2842 | drbd_thread_init(mdev, &mdev->asender, drbd_asender); | 2854 | drbd_thread_init(mdev, &mdev->asender, drbd_asender); |
2843 | 2855 | ||
2844 | mdev->agreed_pro_version = PRO_VERSION_MAX; | 2856 | mdev->agreed_pro_version = PRO_VERSION_MAX; |
2845 | mdev->write_ordering = WO_bio_barrier; | 2857 | mdev->write_ordering = WO_bdev_flush; |
2846 | mdev->resync_wenr = LC_FREE; | 2858 | mdev->resync_wenr = LC_FREE; |
2847 | } | 2859 | } |
2848 | 2860 | ||
@@ -2899,7 +2911,6 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) | |||
2899 | D_ASSERT(list_empty(&mdev->resync_work.list)); | 2911 | D_ASSERT(list_empty(&mdev->resync_work.list)); |
2900 | D_ASSERT(list_empty(&mdev->unplug_work.list)); | 2912 | D_ASSERT(list_empty(&mdev->unplug_work.list)); |
2901 | D_ASSERT(list_empty(&mdev->go_diskless.list)); | 2913 | D_ASSERT(list_empty(&mdev->go_diskless.list)); |
2902 | |||
2903 | } | 2914 | } |
2904 | 2915 | ||
2905 | 2916 | ||
@@ -3660,6 +3671,8 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) | |||
3660 | 3671 | ||
3661 | get_random_bytes(&val, sizeof(u64)); | 3672 | get_random_bytes(&val, sizeof(u64)); |
3662 | _drbd_uuid_set(mdev, UI_CURRENT, val); | 3673 | _drbd_uuid_set(mdev, UI_CURRENT, val); |
3674 | /* get it to stable storage _now_ */ | ||
3675 | drbd_md_sync(mdev); | ||
3663 | } | 3676 | } |
3664 | 3677 | ||
3665 | void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) | 3678 | void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) |
@@ -3756,19 +3769,31 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) | |||
3756 | return 1; | 3769 | return 1; |
3757 | } | 3770 | } |
3758 | 3771 | ||
3772 | void drbd_ldev_destroy(struct drbd_conf *mdev) | ||
3773 | { | ||
3774 | lc_destroy(mdev->resync); | ||
3775 | mdev->resync = NULL; | ||
3776 | lc_destroy(mdev->act_log); | ||
3777 | mdev->act_log = NULL; | ||
3778 | __no_warn(local, | ||
3779 | drbd_free_bc(mdev->ldev); | ||
3780 | mdev->ldev = NULL;); | ||
3781 | |||
3782 | if (mdev->md_io_tmpp) { | ||
3783 | __free_page(mdev->md_io_tmpp); | ||
3784 | mdev->md_io_tmpp = NULL; | ||
3785 | } | ||
3786 | clear_bit(GO_DISKLESS, &mdev->flags); | ||
3787 | } | ||
3788 | |||
3759 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) | 3789 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) |
3760 | { | 3790 | { |
3761 | D_ASSERT(mdev->state.disk == D_FAILED); | 3791 | D_ASSERT(mdev->state.disk == D_FAILED); |
3762 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will | 3792 | /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will |
3763 | * inc/dec it frequently. Once we are D_DISKLESS, no one will touch | 3793 | * inc/dec it frequently. Once we are D_DISKLESS, no one will touch |
3764 | * the protected members anymore, though, so in the after_state_ch work | 3794 | * the protected members anymore, though, so once put_ldev reaches zero |
3765 | * it will be safe to free them. */ | 3795 | * again, it will be safe to free them. */ |
3766 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 3796 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); |
3767 | /* We need to wait for return of references checked out while we still | ||
3768 | * have been D_FAILED, though (drbd_md_sync, bitmap io). */ | ||
3769 | wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); | ||
3770 | |||
3771 | clear_bit(GO_DISKLESS, &mdev->flags); | ||
3772 | return 1; | 3797 | return 1; |
3773 | } | 3798 | } |
3774 | 3799 | ||
@@ -3777,9 +3802,6 @@ void drbd_go_diskless(struct drbd_conf *mdev) | |||
3777 | D_ASSERT(mdev->state.disk == D_FAILED); | 3802 | D_ASSERT(mdev->state.disk == D_FAILED); |
3778 | if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) | 3803 | if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) |
3779 | drbd_queue_work(&mdev->data.work, &mdev->go_diskless); | 3804 | drbd_queue_work(&mdev->data.work, &mdev->go_diskless); |
3780 | /* don't drbd_queue_work_front, | ||
3781 | * we need to serialize with the after_state_ch work | ||
3782 | * of the -> D_FAILED transition. */ | ||
3783 | } | 3805 | } |
3784 | 3806 | ||
3785 | /** | 3807 | /** |