Print this page
4171 clean up spa_feature_*() interfaces
4172 implement extensible_dataset feature for use by other zpool features
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>


1817 zvol_init(void)
1818 {
1819         VERIFY(ddi_soft_state_init(&zfsdev_state, sizeof (zfs_soft_state_t),
1820             1) == 0);
1821         mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
1822 }
1823 
1824 void
1825 zvol_fini(void)
1826 {
1827         mutex_destroy(&zfsdev_state_lock);
1828         ddi_soft_state_fini(&zfsdev_state);
1829 }
1830 
1831 /*ARGSUSED*/
1832 static int
1833 zfs_mvdev_dump_feature_check(void *arg, dmu_tx_t *tx)
1834 {
1835         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
1836 
1837         if (spa_feature_is_active(spa,
1838             &spa_feature_table[SPA_FEATURE_MULTI_VDEV_CRASH_DUMP]))
1839                 return (1);
1840         return (0);
1841 }
1842 
1843 /*ARGSUSED*/
1844 static void
1845 zfs_mvdev_dump_activate_feature_sync(void *arg, dmu_tx_t *tx)
1846 {
1847         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
1848 
1849         spa_feature_incr(spa,
1850             &spa_feature_table[SPA_FEATURE_MULTI_VDEV_CRASH_DUMP], tx);
1851 }
1852 
1853 static int
1854 zvol_dump_init(zvol_state_t *zv, boolean_t resize)
1855 {
1856         dmu_tx_t *tx;
1857         int error;
1858         objset_t *os = zv->zv_objset;
1859         spa_t *spa = dmu_objset_spa(os);
1860         vdev_t *vd = spa->spa_root_vdev;
1861         nvlist_t *nv = NULL;
1862         uint64_t version = spa_version(spa);
1863         enum zio_checksum checksum;
1864 
1865         ASSERT(MUTEX_HELD(&zfsdev_state_lock));
1866         ASSERT(vd->vdev_ops == &vdev_root_ops);
1867 
1868         error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, 0,
1869             DMU_OBJECT_END);
1870         /* wait for dmu_free_long_range to actually free the blocks */
1871         txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
1872 
1873         /*
1874          * If the pool on which the dump device is being initialized has more
1875          * than one child vdev, check that the MULTI_VDEV_CRASH_DUMP feature is
1876          * enabled.  If so, bump that feature's counter to indicate that the
1877          * feature is active. We also check the vdev type to handle the
1878          * following case:
1879          *   # zpool create test raidz disk1 disk2 disk3
1880          *   Now have spa_root_vdev->vdev_children == 1 (the raidz vdev),
1881          *   the raidz vdev itself has 3 children.
1882          */
1883         if (vd->vdev_children > 1 || vd->vdev_ops == &vdev_raidz_ops) {
1884                 if (!spa_feature_is_enabled(spa,
1885                     &spa_feature_table[SPA_FEATURE_MULTI_VDEV_CRASH_DUMP]))
1886                         return (SET_ERROR(ENOTSUP));
1887                 (void) dsl_sync_task(spa_name(spa),
1888                     zfs_mvdev_dump_feature_check,
1889                     zfs_mvdev_dump_activate_feature_sync, NULL, 2);
1890         }
1891 
1892         tx = dmu_tx_create(os);
1893         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1894         dmu_tx_hold_bonus(tx, ZVOL_OBJ);
1895         error = dmu_tx_assign(tx, TXG_WAIT);
1896         if (error) {
1897                 dmu_tx_abort(tx);
1898                 return (error);
1899         }
1900 
1901         /*
1902          * If MULTI_VDEV_CRASH_DUMP is active, use the NOPARITY checksum
1903          * function.  Otherwise, use the old default -- OFF.
1904          */
1905         checksum = spa_feature_is_active(spa,
1906             &spa_feature_table[SPA_FEATURE_MULTI_VDEV_CRASH_DUMP]) ?
1907             ZIO_CHECKSUM_NOPARITY : ZIO_CHECKSUM_OFF;
1908 
1909         /*
1910          * If we are resizing the dump device then we only need to
1911          * update the refreservation to match the newly updated
1912          * zvolsize. Otherwise, we save off the original state of the
1913          * zvol so that we can restore them if the zvol is ever undumpified.
1914          */
1915         if (resize) {
1916                 error = zap_update(os, ZVOL_ZAP_OBJ,
1917                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1,
1918                     &zv->zv_volsize, tx);
1919         } else {
1920                 uint64_t checksum, compress, refresrv, vbs, dedup;
1921 
1922                 error = dsl_prop_get_integer(zv->zv_name,
1923                     zfs_prop_to_name(ZFS_PROP_COMPRESSION), &compress, NULL);
1924                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1925                     zfs_prop_to_name(ZFS_PROP_CHECKSUM), &checksum, NULL);
1926                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1927                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &refresrv, NULL);




1817 zvol_init(void)
1818 {
1819         VERIFY(ddi_soft_state_init(&zfsdev_state, sizeof (zfs_soft_state_t),
1820             1) == 0);
1821         mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
1822 }
1823 
1824 void
1825 zvol_fini(void)
1826 {
1827         mutex_destroy(&zfsdev_state_lock);
1828         ddi_soft_state_fini(&zfsdev_state);
1829 }
1830 
1831 /*ARGSUSED*/
1832 static int
1833 zfs_mvdev_dump_feature_check(void *arg, dmu_tx_t *tx)
1834 {
1835         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
1836 
1837         if (spa_feature_is_active(spa, SPA_FEATURE_MULTI_VDEV_CRASH_DUMP))

1838                 return (1);
1839         return (0);
1840 }
1841 
1842 /*ARGSUSED*/
1843 static void
1844 zfs_mvdev_dump_activate_feature_sync(void *arg, dmu_tx_t *tx)
1845 {
1846         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
1847 
1848         spa_feature_incr(spa, SPA_FEATURE_MULTI_VDEV_CRASH_DUMP, tx);

1849 }
1850 
1851 static int
1852 zvol_dump_init(zvol_state_t *zv, boolean_t resize)
1853 {
1854         dmu_tx_t *tx;
1855         int error;
1856         objset_t *os = zv->zv_objset;
1857         spa_t *spa = dmu_objset_spa(os);
1858         vdev_t *vd = spa->spa_root_vdev;
1859         nvlist_t *nv = NULL;
1860         uint64_t version = spa_version(spa);
1861         enum zio_checksum checksum;
1862 
1863         ASSERT(MUTEX_HELD(&zfsdev_state_lock));
1864         ASSERT(vd->vdev_ops == &vdev_root_ops);
1865 
1866         error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, 0,
1867             DMU_OBJECT_END);
1868         /* wait for dmu_free_long_range to actually free the blocks */
1869         txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
1870 
1871         /*
1872          * If the pool on which the dump device is being initialized has more
1873          * than one child vdev, check that the MULTI_VDEV_CRASH_DUMP feature is
1874          * enabled.  If so, bump that feature's counter to indicate that the
1875          * feature is active. We also check the vdev type to handle the
1876          * following case:
1877          *   # zpool create test raidz disk1 disk2 disk3
1878          *   Now have spa_root_vdev->vdev_children == 1 (the raidz vdev),
1879          *   the raidz vdev itself has 3 children.
1880          */
1881         if (vd->vdev_children > 1 || vd->vdev_ops == &vdev_raidz_ops) {
1882                 if (!spa_feature_is_enabled(spa,
1883                     SPA_FEATURE_MULTI_VDEV_CRASH_DUMP))
1884                         return (SET_ERROR(ENOTSUP));
1885                 (void) dsl_sync_task(spa_name(spa),
1886                     zfs_mvdev_dump_feature_check,
1887                     zfs_mvdev_dump_activate_feature_sync, NULL, 2);
1888         }
1889 
1890         tx = dmu_tx_create(os);
1891         dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
1892         dmu_tx_hold_bonus(tx, ZVOL_OBJ);
1893         error = dmu_tx_assign(tx, TXG_WAIT);
1894         if (error) {
1895                 dmu_tx_abort(tx);
1896                 return (error);
1897         }
1898 
1899         /*
1900          * If MULTI_VDEV_CRASH_DUMP is active, use the NOPARITY checksum
1901          * function.  Otherwise, use the old default -- OFF.
1902          */
1903         checksum = spa_feature_is_active(spa,
1904             SPA_FEATURE_MULTI_VDEV_CRASH_DUMP) ? ZIO_CHECKSUM_NOPARITY :
1905             ZIO_CHECKSUM_OFF;
1906 
1907         /*
1908          * If we are resizing the dump device then we only need to
1909          * update the refreservation to match the newly updated
1910          * zvolsize. Otherwise, we save off the original state of the
1911          * zvol so that we can restore them if the zvol is ever undumpified.
1912          */
1913         if (resize) {
1914                 error = zap_update(os, ZVOL_ZAP_OBJ,
1915                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), 8, 1,
1916                     &zv->zv_volsize, tx);
1917         } else {
1918                 uint64_t checksum, compress, refresrv, vbs, dedup;
1919 
1920                 error = dsl_prop_get_integer(zv->zv_name,
1921                     zfs_prop_to_name(ZFS_PROP_COMPRESSION), &compress, NULL);
1922                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1923                     zfs_prop_to_name(ZFS_PROP_CHECKSUM), &checksum, NULL);
1924                 error = error ? error : dsl_prop_get_integer(zv->zv_name,
1925                     zfs_prop_to_name(ZFS_PROP_REFRESERVATION), &refresrv, NULL);