* Called by the ZFS_IOC_POOL_SCAN ioctl to start a scrub or resilver. * Can also be called to resume a paused scrub. */
| 815 | * Can also be called to resume a paused scrub. |
| 816 | */ |
| 817 | int |
| 818 | dsl_scan(dsl_pool_t *dp, pool_scan_func_t func) |
| 819 | { |
| 820 | spa_t *spa = dp->dp_spa; |
| 821 | dsl_scan_t *scn = dp->dp_scan; |
| 822 | |
| 823 | /* |
| 824 | * Purge all vdev caches and probe all devices. We do this here |
| 825 | * rather than in sync context because this requires a writer lock |
| 826 | * on the spa_config lock, which we can't do from sync context. The |
| 827 | * spa_scrub_reopen flag indicates that vdev_open() should not |
| 828 | * attempt to start another scrub. |
| 829 | */ |
| 830 | spa_vdev_state_enter(spa, SCL_NONE); |
| 831 | spa->spa_scrub_reopen = B_TRUE; |
| 832 | vdev_reopen(spa->spa_root_vdev); |
| 833 | spa->spa_scrub_reopen = B_FALSE; |
| 834 | (void) spa_vdev_state_exit(spa, NULL, 0); |
| 835 | |
| 836 | if (func == POOL_SCAN_RESILVER) { |
| 837 | dsl_scan_restart_resilver(spa->spa_dsl_pool, 0); |
| 838 | return (0); |
| 839 | } |
| 840 | |
| 841 | if (func == POOL_SCAN_SCRUB && dsl_scan_is_paused_scrub(scn)) { |
| 842 | /* got scrub start cmd, resume paused scrub */ |
| 843 | int err = dsl_scrub_set_pause_resume(scn->scn_dp, |
| 844 | POOL_SCRUB_NORMAL); |
| 845 | if (err == 0) { |
| 846 | spa_event_notify(spa, NULL, NULL, ESC_ZFS_SCRUB_RESUME); |
| 847 | return (SET_ERROR(ECANCELED)); |
| 848 | } |
| 849 | |
| 850 | return (SET_ERROR(err)); |
| 851 | } |
| 852 | |
| 853 | return (dsl_sync_task(spa_name(spa), dsl_scan_setup_check, |
| 854 | dsl_scan_setup_sync, &func, 0, ZFS_SPACE_CHECK_EXTRA_RESERVED)); |
| 855 | } |
| 856 | |
| 857 | /* ARGSUSED */ |
| 858 | static void |
no test coverage detected