Print this page
zpool import speedup


  30 #include <sys/cred.h>
  31 #include <sys/zfs_context.h>
  32 #include <sys/dmu_objset.h>
  33 #include <sys/dsl_dir.h>
  34 #include <sys/dsl_dataset.h>
  35 #include <sys/dsl_prop.h>
  36 #include <sys/dsl_pool.h>
  37 #include <sys/dsl_synctask.h>
  38 #include <sys/dsl_deleg.h>
  39 #include <sys/dnode.h>
  40 #include <sys/dbuf.h>
  41 #include <sys/zvol.h>
  42 #include <sys/dmu_tx.h>
  43 #include <sys/zap.h>
  44 #include <sys/zil.h>
  45 #include <sys/dmu_impl.h>
  46 #include <sys/zfs_ioctl.h>
  47 #include <sys/sa.h>
  48 #include <sys/zfs_onexit.h>
  49 #include <sys/dsl_destroy.h>

  50 
  51 /*
  52  * Needed to close a window in dnode_move() that allows the objset to be freed
  53  * before it can be safely accessed.
  54  */
  55 krwlock_t os_lock;
  56 
  57 void
  58 dmu_objset_init(void)
  59 {
  60         rw_init(&os_lock, NULL, RW_DEFAULT, NULL);
  61 }
  62 
  63 void
  64 dmu_objset_fini(void)
  65 {
  66         rw_destroy(&os_lock);
  67 }
  68 
  69 spa_t *


 449                 objset_t *os;
 450                 err = dmu_objset_open_impl(dsl_dataset_get_spa(ds),
 451                     ds, dsl_dataset_get_blkptr(ds), &os);
 452 
 453                 if (err == 0) {
 454                         mutex_enter(&ds->ds_lock);
 455                         ASSERT(ds->ds_objset == NULL);
 456                         ds->ds_objset = os;
 457                         mutex_exit(&ds->ds_lock);
 458                 }
 459         }
 460         *osp = ds->ds_objset;
 461         mutex_exit(&ds->ds_opening_lock);
 462         return (err);
 463 }
 464 
 465 /*
 466  * Holds the pool while the objset is held.  Therefore only one objset
 467  * can be held at a time.
 468  */
 469 int
 470 dmu_objset_hold(const char *name, void *tag, objset_t **osp)
 471 {
 472         dsl_pool_t *dp;
 473         dsl_dataset_t *ds;
 474         int err;
 475 
 476         err = dsl_pool_hold(name, tag, &dp);
 477         if (err != 0)
 478                 return (err);
 479         err = dsl_dataset_hold(dp, name, tag, &ds);
 480         if (err != 0) {
 481                 dsl_pool_rele(dp, tag);
 482                 return (err);
 483         }
 484 
 485         err = dmu_objset_from_ds(ds, osp);
 486         if (err != 0) {
 487                 dsl_dataset_rele(ds, tag);
 488                 dsl_pool_rele(dp, tag);
 489         }
 490 
 491         return (err);
 492 }
 493 












 494 /*
 495  * dsl_pool must not be held when this is called.
 496  * Upon successful return, there will be a longhold on the dataset,
 497  * and the dsl_pool will not be held.
 498  */
 499 int
 500 dmu_objset_own(const char *name, dmu_objset_type_t type,
 501     boolean_t readonly, void *tag, objset_t **osp)
 502 {
 503         dsl_pool_t *dp;
 504         dsl_dataset_t *ds;
 505         int err;
 506 
 507         err = dsl_pool_hold(name, FTAG, &dp);
 508         if (err != 0)
 509                 return (err);
 510         err = dsl_dataset_own(dp, name, tag, &ds);
 511         if (err != 0) {
 512                 dsl_pool_rele(dp, FTAG);
 513                 return (err);
 514         }
 515 
 516         err = dmu_objset_from_ds(ds, osp);
 517         dsl_pool_rele(dp, FTAG);
 518         if (err != 0) {
 519                 dsl_dataset_disown(ds, tag);
 520         } else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) {
 521                 dsl_dataset_disown(ds, tag);
 522                 return (SET_ERROR(EINVAL));
 523         } else if (!readonly && dsl_dataset_is_snapshot(ds)) {
 524                 dsl_dataset_disown(ds, tag);
 525                 return (SET_ERROR(EROFS));
 526         }
 527         return (err);
 528 }
 529 














 530 void
 531 dmu_objset_rele(objset_t *os, void *tag)
 532 {
 533         dsl_pool_t *dp = dmu_objset_pool(os);
 534         dsl_dataset_rele(os->os_dsl_dataset, tag);
 535         dsl_pool_rele(dp, tag);
 536 }
 537 
 538 /*
 539  * When we are called, os MUST refer to an objset associated with a dataset
 540  * that is owned by 'tag'; that is, is held and long held by 'tag' and ds_owner
 541  * == tag.  We will then release and reacquire ownership of the dataset while
 542  * holding the pool config_rwlock to avoid intervening namespace or ownership
 543  * changes may occur.
 544  *
 545  * This exists solely to accommodate zfs_ioc_userspace_upgrade()'s desire to
 546  * release the hold on its dataset and acquire a new one on the dataset of the
 547  * same name so that it can be partially torn down and reconstructed.
 548  */
 549 void


1756 
1757         /* Apply to self. */
1758         return (func(name, arg));
1759 }
1760 
1761 /*
1762  * See comment above dmu_objset_find_impl().
1763  */
1764 int
1765 dmu_objset_find(char *name, int func(const char *, void *), void *arg,
1766     int flags)
1767 {
1768         spa_t *spa;
1769         int error;
1770 
1771         error = spa_open(name, &spa, FTAG);
1772         if (error != 0)
1773                 return (error);
1774         error = dmu_objset_find_impl(spa, name, func, arg, flags);
1775         spa_close(spa, FTAG);










































































































































1776         return (error);
1777 }
1778 
1779 void
1780 dmu_objset_set_user(objset_t *os, void *user_ptr)
1781 {
1782         ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
1783         os->os_user_ptr = user_ptr;
1784 }
1785 
1786 void *
1787 dmu_objset_get_user(objset_t *os)
1788 {
1789         ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
1790         return (os->os_user_ptr);
1791 }
1792 
1793 /*
1794  * Determine name of filesystem, given name of snapshot.
1795  * buf must be at least MAXNAMELEN bytes


  30 #include <sys/cred.h>
  31 #include <sys/zfs_context.h>
  32 #include <sys/dmu_objset.h>
  33 #include <sys/dsl_dir.h>
  34 #include <sys/dsl_dataset.h>
  35 #include <sys/dsl_prop.h>
  36 #include <sys/dsl_pool.h>
  37 #include <sys/dsl_synctask.h>
  38 #include <sys/dsl_deleg.h>
  39 #include <sys/dnode.h>
  40 #include <sys/dbuf.h>
  41 #include <sys/zvol.h>
  42 #include <sys/dmu_tx.h>
  43 #include <sys/zap.h>
  44 #include <sys/zil.h>
  45 #include <sys/dmu_impl.h>
  46 #include <sys/zfs_ioctl.h>
  47 #include <sys/sa.h>
  48 #include <sys/zfs_onexit.h>
  49 #include <sys/dsl_destroy.h>
  50 #include <sys/vdev.h>
  51 
  52 /*
  53  * Needed to close a window in dnode_move() that allows the objset to be freed
  54  * before it can be safely accessed.
  55  */
  56 krwlock_t os_lock;
  57 
  58 void
  59 dmu_objset_init(void)
  60 {
  61         rw_init(&os_lock, NULL, RW_DEFAULT, NULL);
  62 }
  63 
  64 void
  65 dmu_objset_fini(void)
  66 {
  67         rw_destroy(&os_lock);
  68 }
  69 
  70 spa_t *


 450                 objset_t *os;
 451                 err = dmu_objset_open_impl(dsl_dataset_get_spa(ds),
 452                     ds, dsl_dataset_get_blkptr(ds), &os);
 453 
 454                 if (err == 0) {
 455                         mutex_enter(&ds->ds_lock);
 456                         ASSERT(ds->ds_objset == NULL);
 457                         ds->ds_objset = os;
 458                         mutex_exit(&ds->ds_lock);
 459                 }
 460         }
 461         *osp = ds->ds_objset;
 462         mutex_exit(&ds->ds_opening_lock);
 463         return (err);
 464 }
 465 
 466 /*
 467  * Holds the pool while the objset is held.  Therefore only one objset
 468  * can be held at a time.
 469  */
 470 static int
 471 dmu_objset_hold_impl(const char *name, void *tag, objset_t **osp, int lock)
 472 {
 473         dsl_pool_t *dp;
 474         dsl_dataset_t *ds;
 475         int err;
 476 
 477         err = dsl_pool_hold_lock(name, tag, &dp, lock);
 478         if (err != 0)
 479                 return (err);
 480         err = dsl_dataset_hold(dp, name, tag, &ds);
 481         if (err != 0) {
 482                 dsl_pool_rele(dp, tag);
 483                 return (err);
 484         }
 485 
 486         err = dmu_objset_from_ds(ds, osp);
 487         if (err != 0) {
 488                 dsl_dataset_rele(ds, tag);
 489                 dsl_pool_rele(dp, tag);
 490         }
 491 
 492         return (err);
 493 }
 494 
 495 int
 496 dmu_objset_hold(const char *name, void *tag, objset_t **osp)
 497 {
 498         return (dmu_objset_hold_impl(name, tag, osp, 1));
 499 }
 500 
 501 int
 502 dmu_objset_hold_nolock(const char *name, void *tag, objset_t **osp)
 503 {
 504         return (dmu_objset_hold_impl(name, tag, osp, 0));
 505 }
 506 
 507 /*
 508  * dsl_pool must not be held when this is called.
 509  * Upon successful return, there will be a longhold on the dataset,
 510  * and the dsl_pool will not be held.
 511  */
 512 static int
 513 dmu_objset_own_impl(const char *name, dmu_objset_type_t type,
 514     boolean_t readonly, void *tag, objset_t **osp, int lock)
 515 {
 516         dsl_pool_t *dp;
 517         dsl_dataset_t *ds;
 518         int err;
 519 
 520         err = dsl_pool_hold_lock(name, FTAG, &dp, lock);
 521         if (err != 0)
 522                 return (err);
 523         err = dsl_dataset_own(dp, name, tag, &ds);
 524         if (err != 0) {
 525                 dsl_pool_rele(dp, FTAG);
 526                 return (err);
 527         }
 528 
 529         err = dmu_objset_from_ds(ds, osp);
 530         dsl_pool_rele(dp, FTAG);
 531         if (err != 0) {
 532                 dsl_dataset_disown(ds, tag);
 533         } else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) {
 534                 dsl_dataset_disown(ds, tag);
 535                 return (SET_ERROR(EINVAL));
 536         } else if (!readonly && dsl_dataset_is_snapshot(ds)) {
 537                 dsl_dataset_disown(ds, tag);
 538                 return (SET_ERROR(EROFS));
 539         }
 540         return (err);
 541 }
 542 
 543 int
 544 dmu_objset_own(const char *name, dmu_objset_type_t type,
 545     boolean_t readonly, void *tag, objset_t **osp)
 546 {
 547         return (dmu_objset_own_impl(name, type, readonly, tag, osp, 1));
 548 }
 549 
 550 int
 551 dmu_objset_own_nolock(const char *name, dmu_objset_type_t type,
 552     boolean_t readonly, void *tag, objset_t **osp)
 553 {
 554         return (dmu_objset_own_impl(name, type, readonly, tag, osp, 0));
 555 }
 556 
 557 void
 558 dmu_objset_rele(objset_t *os, void *tag)
 559 {
 560         dsl_pool_t *dp = dmu_objset_pool(os);
 561         dsl_dataset_rele(os->os_dsl_dataset, tag);
 562         dsl_pool_rele(dp, tag);
 563 }
 564 
 565 /*
 566  * When we are called, os MUST refer to an objset associated with a dataset
 567  * that is owned by 'tag'; that is, is held and long held by 'tag' and ds_owner
 568  * == tag.  We will then release and reacquire ownership of the dataset while
 569  * holding the pool config_rwlock to avoid intervening namespace or ownership
 570  * changes may occur.
 571  *
 572  * This exists solely to accommodate zfs_ioc_userspace_upgrade()'s desire to
 573  * release the hold on its dataset and acquire a new one on the dataset of the
 574  * same name so that it can be partially torn down and reconstructed.
 575  */
 576 void


1783 
1784         /* Apply to self. */
1785         return (func(name, arg));
1786 }
1787 
1788 /*
1789  * See comment above dmu_objset_find_impl().
1790  */
1791 int
1792 dmu_objset_find(char *name, int func(const char *, void *), void *arg,
1793     int flags)
1794 {
1795         spa_t *spa;
1796         int error;
1797 
1798         error = spa_open(name, &spa, FTAG);
1799         if (error != 0)
1800                 return (error);
1801         error = dmu_objset_find_impl(spa, name, func, arg, flags);
1802         spa_close(spa, FTAG);
1803 
1804         return (error);
1805 }
1806 
1807 typedef struct dmu_objset_find_ctx {
1808         taskq_t         *dc_tq;
1809         spa_t           *dc_spa;
1810         char            *dc_name;
1811         int             (*dc_func)(const char *, void *);
1812         void            *dc_arg;
1813         int             dc_flags;
1814         kmutex_t        *dc_error_lock;
1815         int             *dc_error;
1816 } dmu_objset_find_ctx_t;
1817 
1818 static void
1819 dmu_objset_find_parallel_impl(void *arg)
1820 {
1821         dmu_objset_find_ctx_t *dcp = arg;
1822         dsl_dir_t *dd;
1823         dsl_pool_t *dp = spa_get_dsl(dcp->dc_spa);
1824         dsl_dataset_t *ds;
1825         zap_cursor_t zc;
1826         zap_attribute_t *attr;
1827         char *child;
1828         dmu_objset_find_ctx_t *child_dcp;
1829         uint64_t thisobj;
1830         int err;
1831 
1832         /* don't process if there already was an error */
1833         if (*dcp->dc_error)
1834                 goto out;
1835 
1836         dsl_pool_config_enter(dp, FTAG);
1837 
1838         err = dsl_dir_hold(dp, dcp->dc_name, FTAG, &dd, NULL);
1839         if (err != 0) {
1840                 dsl_pool_config_exit(dp, FTAG);
1841                 goto fail;
1842         }
1843 
1844         /* Don't visit hidden ($MOS & $ORIGIN) objsets. */
1845         if (dd->dd_myname[0] == '$') {
1846                 dsl_dir_rele(dd, FTAG);
1847                 dsl_pool_config_exit(dp, FTAG);
1848                 goto out;
1849         }
1850 
1851         thisobj = dd->dd_phys->dd_head_dataset_obj;
1852         attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
1853 
1854         /*
1855          * Iterate over all children.
1856          */
1857         if (dcp->dc_flags & DS_FIND_CHILDREN) {
1858                 for (zap_cursor_init(&zc, dp->dp_meta_objset,
1859                     dd->dd_phys->dd_child_dir_zapobj);
1860                     zap_cursor_retrieve(&zc, attr) == 0;
1861                     (void) zap_cursor_advance(&zc)) {
1862                         ASSERT3U(attr->za_integer_length, ==,
1863                             sizeof (uint64_t));
1864                         ASSERT3U(attr->za_num_integers, ==, 1);
1865 
1866                         child = kmem_asprintf("%s/%s", dcp->dc_name,
1867                             attr->za_name);
1868                         dsl_pool_config_exit(dp, FTAG);
1869                         child_dcp = kmem_alloc(sizeof(*child_dcp), KM_SLEEP);
1870                         *child_dcp = *dcp;
1871                         child_dcp->dc_name = child;
1872                         taskq_dispatch(dcp->dc_tq,
1873                             dmu_objset_find_parallel_impl, child_dcp, TQ_SLEEP);
1874                         dsl_pool_config_enter(dp, FTAG);
1875                 }
1876                 zap_cursor_fini(&zc);
1877         }
1878 
1879         dsl_dir_rele(dd, FTAG);
1880         kmem_free(attr, sizeof (zap_attribute_t));
1881         dsl_pool_config_exit(dp, FTAG);
1882 
1883         err = dcp->dc_func(dcp->dc_name, dcp->dc_arg);
1884 
1885 fail:
1886         if (err) {
1887                 mutex_enter(dcp->dc_error_lock);
1888                 /* only keep first error */
1889                 if (*dcp->dc_error == 0)
1890                         *dcp->dc_error = err;
1891                 mutex_exit(dcp->dc_error_lock);
1892         }
1893 
1894 out:
1895         strfree(dcp->dc_name);
1896         kmem_free(dcp, sizeof(*dcp));
1897 }
1898 
1899 int
1900 dmu_objset_find_parallel(char *name, int func(const char *, void *), void *arg,
1901     int flags)
1902 {
1903         spa_t *spa;
1904         int error;
1905         taskq_t *tq = NULL;
1906         int ntasks;
1907         dmu_objset_find_ctx_t *dcp;
1908         kmutex_t err_lock;
1909 
1910         error = spa_open(name, &spa, FTAG);
1911         if (error != 0)
1912                 return (error);
1913 
1914         ntasks = vdev_count_leaves(spa) * 4;
1915         tq = taskq_create("dmu_objset_find", ntasks, minclsyspri, ntasks,
1916             INT_MAX, 0);
1917         if (!tq) {
1918                 spa_close(spa, FTAG);
1919                 return (dmu_objset_find(name, func, arg, flags));
1920         }
1921 
1922         mutex_init(&err_lock, NULL, MUTEX_DEFAULT, NULL);
1923         dcp = kmem_alloc(sizeof(*dcp), KM_SLEEP);
1924         dcp->dc_tq = tq;
1925         dcp->dc_spa = spa;
1926         dcp->dc_name = strdup(name);
1927         dcp->dc_func = func;
1928         dcp->dc_arg = arg;
1929         dcp->dc_flags = flags;
1930         dcp->dc_error_lock = &err_lock;
1931         dcp->dc_error = &error;
1932         /* dcp and dc_name will be freed by task */
1933         taskq_dispatch(tq, dmu_objset_find_parallel_impl, dcp, TQ_SLEEP);
1934 
1935         taskq_wait(tq);
1936         taskq_destroy(tq);
1937         mutex_destroy(&err_lock);
1938 
1939         spa_close(spa, FTAG);
1940 
1941         return (error);
1942 }
1943 
1944 void
1945 dmu_objset_set_user(objset_t *os, void *user_ptr)
1946 {
1947         ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
1948         os->os_user_ptr = user_ptr;
1949 }
1950 
1951 void *
1952 dmu_objset_get_user(objset_t *os)
1953 {
1954         ASSERT(MUTEX_HELD(&os->os_user_ptr_lock));
1955         return (os->os_user_ptr);
1956 }
1957 
1958 /*
1959  * Determine name of filesystem, given name of snapshot.
1960  * buf must be at least MAXNAMELEN bytes