Print this page
3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero


 814         if (origin == NULL) {
 815                 dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
 816         } else {
 817                 dsl_dataset_t *ohds;
 818 
 819                 dsphys->ds_prev_snap_obj = origin->ds_object;
 820                 dsphys->ds_prev_snap_txg =
 821                     origin->ds_phys->ds_creation_txg;
 822                 dsphys->ds_referenced_bytes =
 823                     origin->ds_phys->ds_referenced_bytes;
 824                 dsphys->ds_compressed_bytes =
 825                     origin->ds_phys->ds_compressed_bytes;
 826                 dsphys->ds_uncompressed_bytes =
 827                     origin->ds_phys->ds_uncompressed_bytes;
 828                 dsphys->ds_bp = origin->ds_phys->ds_bp;
 829                 dsphys->ds_flags |= origin->ds_phys->ds_flags;
 830 
 831                 dmu_buf_will_dirty(origin->ds_dbuf, tx);
 832                 origin->ds_phys->ds_num_children++;
 833 
 834                 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp,
 835                     origin->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ohds));
 836                 dsphys->ds_deadlist_obj = dsl_deadlist_clone(&ohds->ds_deadlist,
 837                     dsphys->ds_prev_snap_txg, dsphys->ds_prev_snap_obj, tx);
 838                 dsl_dataset_rele(ohds, FTAG);
 839 
 840                 if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) {
 841                         if (origin->ds_phys->ds_next_clones_obj == 0) {
 842                                 origin->ds_phys->ds_next_clones_obj =
 843                                     zap_create(mos,
 844                                     DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
 845                         }
 846                         VERIFY(0 == zap_add_int(mos,
 847                             origin->ds_phys->ds_next_clones_obj,
 848                             dsobj, tx));
 849                 }
 850 
 851                 dmu_buf_will_dirty(dd->dd_dbuf, tx);
 852                 dd->dd_phys->dd_origin_obj = origin->ds_object;
 853                 if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
 854                         if (origin->ds_dir->dd_phys->dd_clones == 0) {
 855                                 dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
 856                                 origin->ds_dir->dd_phys->dd_clones =
 857                                     zap_create(mos,
 858                                     DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
 859                         }
 860                         VERIFY3U(0, ==, zap_add_int(mos,
 861                             origin->ds_dir->dd_phys->dd_clones, dsobj, tx));
 862                 }
 863         }
 864 
 865         if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
 866                 dsphys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
 867 
 868         dmu_buf_rele(dbuf, FTAG);
 869 
 870         dmu_buf_will_dirty(dd->dd_dbuf, tx);
 871         dd->dd_phys->dd_head_dataset_obj = dsobj;
 872 
 873         return (dsobj);
 874 }
 875 
 876 uint64_t
 877 dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
 878     dsl_dataset_t *origin, uint64_t flags, cred_t *cr, dmu_tx_t *tx)
 879 {
 880         dsl_pool_t *dp = pdd->dd_pool;


 883 
 884         ASSERT(lastname[0] != '@');
 885 
 886         ddobj = dsl_dir_create_sync(dp, pdd, lastname, tx);
 887         VERIFY(0 == dsl_dir_open_obj(dp, ddobj, lastname, FTAG, &dd));
 888 
 889         dsobj = dsl_dataset_create_sync_dd(dd, origin, flags, tx);
 890 
 891         dsl_deleg_set_create_perms(dd, tx, cr);
 892 
 893         dsl_dir_close(dd, FTAG);
 894 
 895         /*
 896          * If we are creating a clone, make sure we zero out any stale
 897          * data from the origin snapshots zil header.
 898          */
 899         if (origin != NULL) {
 900                 dsl_dataset_t *ds;
 901                 objset_t *os;
 902 
 903                 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
 904                 VERIFY3U(0, ==, dmu_objset_from_ds(ds, &os));
 905                 bzero(&os->os_zil_header, sizeof (os->os_zil_header));
 906                 dsl_dataset_dirty(ds, tx);
 907                 dsl_dataset_rele(ds, FTAG);
 908         }
 909 
 910         return (dsobj);
 911 }
 912 
 913 /*
 914  * The snapshots must all be in the same pool.
 915  */
 916 int
 917 dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer,
 918     nvlist_t *errlist)
 919 {
 920         int err;
 921         dsl_sync_task_t *dst;
 922         spa_t *spa;
 923         nvpair_t *pair;
 924         dsl_sync_task_group_t *dstg;


1487 static void
1488 remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj, dmu_tx_t *tx)
1489 {
1490         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
1491         uint64_t count;
1492         int err;
1493 
1494         ASSERT(ds->ds_phys->ds_num_children >= 2);
1495         err = zap_remove_int(mos, ds->ds_phys->ds_next_clones_obj, obj, tx);
1496         /*
1497          * The err should not be ENOENT, but a bug in a previous version
1498          * of the code could cause upgrade_clones_cb() to not set
1499          * ds_next_snap_obj when it should, leading to a missing entry.
1500          * If we knew that the pool was created after
1501          * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
1502          * ENOENT.  However, at least we can check that we don't have
1503          * too many entries in the next_clones_obj even after failing to
1504          * remove this one.
1505          */
1506         if (err != ENOENT) {
1507                 VERIFY3U(err, ==, 0);
1508         }
1509         ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
1510             &count));
1511         ASSERT3U(count, <=, ds->ds_phys->ds_num_children - 2);
1512 }
1513 
1514 static void
1515 dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)
1516 {
1517         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
1518         zap_cursor_t zc;
1519         zap_attribute_t za;
1520 
1521         /*
1522          * If it is the old version, dd_clones doesn't exist so we can't
1523          * find the clones, but deadlist_remove_key() is a no-op so it
1524          * doesn't matter.
1525          */
1526         if (ds->ds_dir->dd_phys->dd_clones == 0)
1527                 return;
1528 
1529         for (zap_cursor_init(&zc, mos, ds->ds_dir->dd_phys->dd_clones);
1530             zap_cursor_retrieve(&zc, &za) == 0;
1531             zap_cursor_advance(&zc)) {
1532                 dsl_dataset_t *clone;
1533 
1534                 VERIFY3U(0, ==, dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
1535                     za.za_first_integer, FTAG, &clone));
1536                 if (clone->ds_dir->dd_origin_txg > mintxg) {
1537                         dsl_deadlist_remove_key(&clone->ds_deadlist,
1538                             mintxg, tx);
1539                         dsl_dataset_remove_clones_key(clone, mintxg, tx);
1540                 }
1541                 dsl_dataset_rele(clone, FTAG);
1542         }
1543         zap_cursor_fini(&zc);
1544 }
1545 
1546 struct process_old_arg {
1547         dsl_dataset_t *ds;
1548         dsl_dataset_t *ds_prev;
1549         boolean_t after_branch_point;
1550         zio_t *pio;
1551         uint64_t used, comp, uncomp;
1552 };
1553 
1554 static int


1572                 dsl_free_sync(poa->pio, dp, tx->tx_txg, bp);
1573         }
1574         return (0);
1575 }
1576 
1577 static void
1578 process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
1579     dsl_dataset_t *ds_next, boolean_t after_branch_point, dmu_tx_t *tx)
1580 {
1581         struct process_old_arg poa = { 0 };
1582         dsl_pool_t *dp = ds->ds_dir->dd_pool;
1583         objset_t *mos = dp->dp_meta_objset;
1584 
1585         ASSERT(ds->ds_deadlist.dl_oldfmt);
1586         ASSERT(ds_next->ds_deadlist.dl_oldfmt);
1587 
1588         poa.ds = ds;
1589         poa.ds_prev = ds_prev;
1590         poa.after_branch_point = after_branch_point;
1591         poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
1592         VERIFY3U(0, ==, bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
1593             process_old_cb, &poa, tx));
1594         VERIFY3U(zio_wait(poa.pio), ==, 0);
1595         ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
1596 
1597         /* change snapused */
1598         dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
1599             -poa.used, -poa.comp, -poa.uncomp, tx);
1600 
1601         /* swap next's deadlist to our deadlist */
1602         dsl_deadlist_close(&ds->ds_deadlist);
1603         dsl_deadlist_close(&ds_next->ds_deadlist);
1604         SWITCH64(ds_next->ds_phys->ds_deadlist_obj,
1605             ds->ds_phys->ds_deadlist_obj);
1606         dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj);
1607         dsl_deadlist_open(&ds_next->ds_deadlist, mos,
1608             ds_next->ds_phys->ds_deadlist_obj);
1609 }
1610 
1611 static int
1612 old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
1613 {
1614         int err;
1615         struct killarg ka;
1616 
1617         /*
1618          * Free everything that we point to (that's born after
1619          * the previous snapshot, if we are a clone)
1620          *
1621          * NB: this should be very quick, because we already
1622          * freed all the objects in open context.
1623          */
1624         ka.ds = ds;
1625         ka.tx = tx;
1626         err = traverse_dataset(ds,
1627             ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
1628             kill_blkptr, &ka);
1629         ASSERT3U(err, ==, 0);
1630         ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
1631 
1632         return (err);
1633 }
1634 
1635 void
1636 dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
1637 {
1638         struct dsl_ds_destroyarg *dsda = arg1;
1639         dsl_dataset_t *ds = dsda->ds;
1640         int err;
1641         int after_branch_point = FALSE;
1642         dsl_pool_t *dp = ds->ds_dir->dd_pool;
1643         objset_t *mos = dp->dp_meta_objset;
1644         dsl_dataset_t *ds_prev = NULL;
1645         boolean_t wont_destroy;
1646         uint64_t obj;
1647 
1648         wont_destroy = (dsda->defer &&
1649             (ds->ds_userrefs > 0 || ds->ds_phys->ds_num_children > 1));


1665         /* We need to log before removing it from the namespace. */
1666         spa_history_log_internal_ds(ds, "destroy", tx, "");
1667 
1668         /* signal any waiters that this dataset is going away */
1669         mutex_enter(&ds->ds_lock);
1670         ds->ds_owner = dsl_reaper;
1671         cv_broadcast(&ds->ds_exclusive_cv);
1672         mutex_exit(&ds->ds_lock);
1673 
1674         /* Remove our reservation */
1675         if (ds->ds_reserved != 0) {
1676                 dsl_prop_setarg_t psa;
1677                 uint64_t value = 0;
1678 
1679                 dsl_prop_setarg_init_uint64(&psa, "refreservation",
1680                     (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
1681                     &value);
1682                 psa.psa_effective_value = 0;    /* predict default value */
1683 
1684                 dsl_dataset_set_reservation_sync(ds, &psa, tx);
1685                 ASSERT3U(ds->ds_reserved, ==, 0);
1686         }
1687 
1688         ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock));
1689 
1690         dsl_scan_ds_destroyed(ds, tx);
1691 
1692         obj = ds->ds_object;
1693 
1694         if (ds->ds_phys->ds_prev_snap_obj != 0) {
1695                 if (ds->ds_prev) {
1696                         ds_prev = ds->ds_prev;
1697                 } else {
1698                         VERIFY(0 == dsl_dataset_hold_obj(dp,
1699                             ds->ds_phys->ds_prev_snap_obj, FTAG, &ds_prev));
1700                 }
1701                 after_branch_point =
1702                     (ds_prev->ds_phys->ds_next_snap_obj != obj);
1703 
1704                 dmu_buf_will_dirty(ds_prev->ds_dbuf, tx);
1705                 if (after_branch_point &&


1802                          * were previously shared by only this snapshot
1803                          * and it.  Those blocks will be born after the
1804                          * prev snap and before this snap, and will have
1805                          * died after the next snap and before the one
1806                          * after that (ie. be on the snap after next's
1807                          * deadlist).
1808                          */
1809                         VERIFY(0 == dsl_dataset_hold_obj(dp,
1810                             ds_next->ds_phys->ds_next_snap_obj,
1811                             FTAG, &ds_nextnext));
1812                         dsl_deadlist_space_range(&ds_nextnext->ds_deadlist,
1813                             ds->ds_phys->ds_prev_snap_txg,
1814                             ds->ds_phys->ds_creation_txg,
1815                             &used, &comp, &uncomp);
1816                         ds_next->ds_phys->ds_unique_bytes += used;
1817                         dsl_dataset_rele(ds_nextnext, FTAG);
1818                         ASSERT3P(ds_next->ds_prev, ==, NULL);
1819 
1820                         /* Collapse range in this head. */
1821                         dsl_dataset_t *hds;
1822                         VERIFY3U(0, ==, dsl_dataset_hold_obj(dp,
1823                             ds->ds_dir->dd_phys->dd_head_dataset_obj,
1824                             FTAG, &hds));
1825                         dsl_deadlist_remove_key(&hds->ds_deadlist,
1826                             ds->ds_phys->ds_creation_txg, tx);
1827                         dsl_dataset_rele(hds, FTAG);
1828 
1829                 } else {
1830                         ASSERT3P(ds_next->ds_prev, ==, ds);
1831                         dsl_dataset_drop_ref(ds_next->ds_prev, ds_next);
1832                         ds_next->ds_prev = NULL;
1833                         if (ds_prev) {
1834                                 VERIFY(0 == dsl_dataset_get_ref(dp,
1835                                     ds->ds_phys->ds_prev_snap_obj,
1836                                     ds_next, &ds_next->ds_prev));
1837                         }
1838 
1839                         dsl_dataset_recalc_head_uniq(ds_next);
1840 
1841                         /*
1842                          * Reduce the amount of our unconsmed refreservation


1891                         }
1892 
1893                         used = ds->ds_dir->dd_phys->dd_used_bytes;
1894                         comp = ds->ds_dir->dd_phys->dd_compressed_bytes;
1895                         uncomp = ds->ds_dir->dd_phys->dd_uncompressed_bytes;
1896 
1897                         ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
1898                             ds->ds_phys->ds_unique_bytes == used);
1899 
1900                         bptree_add(dp->dp_meta_objset, dp->dp_bptree_obj,
1901                             &ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
1902                             used, comp, uncomp, tx);
1903                         dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
1904                             -used, -comp, -uncomp, tx);
1905                         dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
1906                             used, comp, uncomp, tx);
1907                 }
1908 
1909                 if (ds->ds_prev != NULL) {
1910                         if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
1911                                 VERIFY3U(0, ==, zap_remove_int(mos,
1912                                     ds->ds_prev->ds_dir->dd_phys->dd_clones,
1913                                     ds->ds_object, tx));
1914                         }
1915                         dsl_dataset_rele(ds->ds_prev, ds);
1916                         ds->ds_prev = ds_prev = NULL;
1917                 }
1918         }
1919 
1920         /*
1921          * This must be done after the dsl_traverse(), because it will
1922          * re-open the objset.
1923          */
1924         if (ds->ds_objset) {
1925                 dmu_objset_evict(ds->ds_objset);
1926                 ds->ds_objset = NULL;
1927         }
1928 
1929         if (ds->ds_dir->dd_phys->dd_head_dataset_obj == ds->ds_object) {
1930                 /* Erase the link in the dir */
1931                 dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
1932                 ds->ds_dir->dd_phys->dd_head_dataset_obj = 0;
1933                 ASSERT(ds->ds_phys->ds_snapnames_zapobj != 0);
1934                 err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx);
1935                 ASSERT(err == 0);
1936         } else {
1937                 /* remove from snapshot namespace */
1938                 dsl_dataset_t *ds_head;
1939                 ASSERT(ds->ds_phys->ds_snapnames_zapobj == 0);
1940                 VERIFY(0 == dsl_dataset_hold_obj(dp,
1941                     ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head));
1942                 VERIFY(0 == dsl_dataset_get_snapname(ds));
1943 #ifdef ZFS_DEBUG
1944                 {
1945                         uint64_t val;
1946 
1947                         err = dsl_dataset_snap_lookup(ds_head,
1948                             ds->ds_snapname, &val);
1949                         ASSERT3U(err, ==, 0);
1950                         ASSERT3U(val, ==, obj);
1951                 }
1952 #endif
1953                 err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx);
1954                 ASSERT(err == 0);
1955                 dsl_dataset_rele(ds_head, FTAG);
1956         }
1957 
1958         if (ds_prev && ds->ds_prev != ds_prev)
1959                 dsl_dataset_rele(ds_prev, FTAG);
1960 
1961         spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
1962 
1963         if (ds->ds_phys->ds_next_clones_obj != 0) {
1964                 uint64_t count;
1965                 ASSERT(0 == zap_count(mos,
1966                     ds->ds_phys->ds_next_clones_obj, &count) && count == 0);
1967                 VERIFY(0 == dmu_object_free(mos,
1968                     ds->ds_phys->ds_next_clones_obj, tx));
1969         }


2096         dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes;
2097         dsphys->ds_flags = ds->ds_phys->ds_flags;
2098         dsphys->ds_bp = ds->ds_phys->ds_bp;
2099         dmu_buf_rele(dbuf, FTAG);
2100 
2101         ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0);
2102         if (ds->ds_prev) {
2103                 uint64_t next_clones_obj =
2104                     ds->ds_prev->ds_phys->ds_next_clones_obj;
2105                 ASSERT(ds->ds_prev->ds_phys->ds_next_snap_obj ==
2106                     ds->ds_object ||
2107                     ds->ds_prev->ds_phys->ds_num_children > 1);
2108                 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) {
2109                         dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
2110                         ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==,
2111                             ds->ds_prev->ds_phys->ds_creation_txg);
2112                         ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj;
2113                 } else if (next_clones_obj != 0) {
2114                         remove_from_next_clones(ds->ds_prev,
2115                             dsphys->ds_next_snap_obj, tx);
2116                         VERIFY3U(0, ==, zap_add_int(mos,
2117                             next_clones_obj, dsobj, tx));
2118                 }
2119         }
2120 
2121         /*
2122          * If we have a reference-reservation on this dataset, we will
2123          * need to increase the amount of refreservation being charged
2124          * since our unique space is going to zero.
2125          */
2126         if (ds->ds_reserved) {
2127                 int64_t delta;
2128                 ASSERT(DS_UNIQUE_IS_ACCURATE(ds));
2129                 delta = MIN(ds->ds_phys->ds_unique_bytes, ds->ds_reserved);
2130                 dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV,
2131                     delta, 0, 0, tx);
2132         }
2133 
2134         dmu_buf_will_dirty(ds->ds_dbuf, tx);
2135         zfs_dbgmsg("taking snapshot %s@%s/%llu; newkey=%llu",
2136             ds->ds_dir->dd_myname, snapname, dsobj,


2186 static void
2187 get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
2188 {
2189         uint64_t count = 0;
2190         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
2191         zap_cursor_t zc;
2192         zap_attribute_t za;
2193         nvlist_t *propval;
2194         nvlist_t *val;
2195 
2196         rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
2197         VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2198         VERIFY(nvlist_alloc(&val, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2199 
2200         /*
2201          * There may me missing entries in ds_next_clones_obj
2202          * due to a bug in a previous version of the code.
2203          * Only trust it if it has the right number of entries.
2204          */
2205         if (ds->ds_phys->ds_next_clones_obj != 0) {
2206                 ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
2207                     &count));
2208         }
2209         if (count != ds->ds_phys->ds_num_children - 1) {
2210                 goto fail;
2211         }
2212         for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
2213             zap_cursor_retrieve(&zc, &za) == 0;
2214             zap_cursor_advance(&zc)) {
2215                 dsl_dataset_t *clone;
2216                 char buf[ZFS_MAXNAMELEN];
2217                 /*
2218                  * Even though we hold the dp_config_rwlock, the dataset
2219                  * may fail to open, returning ENOENT.  If there is a
2220                  * thread concurrently attempting to destroy this
2221                  * dataset, it will have the ds_rwlock held for
2222                  * RW_WRITER.  Our call to dsl_dataset_hold_obj() ->
2223                  * dsl_dataset_hold_ref() will fail its
2224                  * rw_tryenter(&ds->ds_rwlock, RW_READER), drop the
2225                  * dp_config_rwlock, and wait for the destroy progress
2226                  * and signal ds_exclusive_cv.  If the destroy was


2425         return (err);
2426 }
2427 
2428 static void
2429 dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
2430 {
2431         dsl_dataset_t *ds = arg1;
2432         const char *newsnapname = arg2;
2433         dsl_dir_t *dd = ds->ds_dir;
2434         objset_t *mos = dd->dd_pool->dp_meta_objset;
2435         dsl_dataset_t *hds;
2436         int err;
2437 
2438         ASSERT(ds->ds_phys->ds_next_snap_obj != 0);
2439 
2440         VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool,
2441             dd->dd_phys->dd_head_dataset_obj, FTAG, &hds));
2442 
2443         VERIFY(0 == dsl_dataset_get_snapname(ds));
2444         err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
2445         ASSERT3U(err, ==, 0);
2446         mutex_enter(&ds->ds_lock);
2447         (void) strcpy(ds->ds_snapname, newsnapname);
2448         mutex_exit(&ds->ds_lock);
2449         err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
2450             ds->ds_snapname, 8, 1, &ds->ds_object, tx);
2451         ASSERT3U(err, ==, 0);
2452 
2453         spa_history_log_internal_ds(ds, "rename", tx,
2454             "-> @%s", newsnapname);
2455         dsl_dataset_rele(hds, FTAG);
2456 }
2457 
2458 struct renamesnaparg {
2459         dsl_sync_task_group_t *dstg;
2460         char failed[MAXPATHLEN];
2461         char *oldsnap;
2462         char *newsnap;
2463 };
2464 
2465 static int
2466 dsl_snapshot_rename_one(const char *name, void *arg)
2467 {
2468         struct renamesnaparg *ra = arg;
2469         dsl_dataset_t *ds = NULL;
2470         char *snapname;
2471         int err;


2789         snap = list_head(&pa->origin_snaps);
2790         origin_head = snap->ds;
2791 
2792         /*
2793          * We need to explicitly open odd, since origin_ds's dd will be
2794          * changing.
2795          */
2796         VERIFY(0 == dsl_dir_open_obj(dp, origin_ds->ds_dir->dd_object,
2797             NULL, FTAG, &odd));
2798 
2799         /* change origin's next snap */
2800         dmu_buf_will_dirty(origin_ds->ds_dbuf, tx);
2801         oldnext_obj = origin_ds->ds_phys->ds_next_snap_obj;
2802         snap = list_tail(&pa->clone_snaps);
2803         ASSERT3U(snap->ds->ds_phys->ds_prev_snap_obj, ==, origin_ds->ds_object);
2804         origin_ds->ds_phys->ds_next_snap_obj = snap->ds->ds_object;
2805 
2806         /* change the origin's next clone */
2807         if (origin_ds->ds_phys->ds_next_clones_obj) {
2808                 remove_from_next_clones(origin_ds, snap->ds->ds_object, tx);
2809                 VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset,
2810                     origin_ds->ds_phys->ds_next_clones_obj,
2811                     oldnext_obj, tx));
2812         }
2813 
2814         /* change origin */
2815         dmu_buf_will_dirty(dd->dd_dbuf, tx);
2816         ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object);
2817         dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj;
2818         dd->dd_origin_txg = origin_head->ds_dir->dd_origin_txg;
2819         dmu_buf_will_dirty(odd->dd_dbuf, tx);
2820         odd->dd_phys->dd_origin_obj = origin_ds->ds_object;
2821         origin_head->ds_dir->dd_origin_txg =
2822             origin_ds->ds_phys->ds_creation_txg;
2823 
2824         /* change dd_clone entries */
2825         if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
2826                 VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
2827                     odd->dd_phys->dd_clones, hds->ds_object, tx));
2828                 VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset,
2829                     pa->origin_origin->ds_dir->dd_phys->dd_clones,
2830                     hds->ds_object, tx));
2831 
2832                 VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
2833                     pa->origin_origin->ds_dir->dd_phys->dd_clones,
2834                     origin_head->ds_object, tx));
2835                 if (dd->dd_phys->dd_clones == 0) {
2836                         dd->dd_phys->dd_clones = zap_create(dp->dp_meta_objset,
2837                             DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
2838                 }
2839                 VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset,
2840                     dd->dd_phys->dd_clones, origin_head->ds_object, tx));
2841 
2842         }
2843 
2844         /* move snapshots to this dir */
2845         for (snap = list_head(&pa->shared_snaps); snap;
2846             snap = list_next(&pa->shared_snaps, snap)) {
2847                 dsl_dataset_t *ds = snap->ds;
2848 
2849                 /* unregister props as dsl_dir is changing */
2850                 if (ds->ds_objset) {
2851                         dmu_objset_evict(ds->ds_objset);
2852                         ds->ds_objset = NULL;
2853                 }
2854                 /* move snap name entry */
2855                 VERIFY(0 == dsl_dataset_get_snapname(ds));
2856                 VERIFY(0 == dsl_dataset_snap_remove(origin_head,
2857                     ds->ds_snapname, tx));
2858                 VERIFY(0 == zap_add(dp->dp_meta_objset,
2859                     hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname,


2872                 if (ds->ds_phys->ds_next_clones_obj &&
2873                     spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
2874                         zap_cursor_t zc;
2875                         zap_attribute_t za;
2876 
2877                         for (zap_cursor_init(&zc, dp->dp_meta_objset,
2878                             ds->ds_phys->ds_next_clones_obj);
2879                             zap_cursor_retrieve(&zc, &za) == 0;
2880                             zap_cursor_advance(&zc)) {
2881                                 dsl_dataset_t *cnds;
2882                                 uint64_t o;
2883 
2884                                 if (za.za_first_integer == oldnext_obj) {
2885                                         /*
2886                                          * We've already moved the
2887                                          * origin's reference.
2888                                          */
2889                                         continue;
2890                                 }
2891 
2892                                 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp,
2893                                     za.za_first_integer, FTAG, &cnds));
2894                                 o = cnds->ds_dir->dd_phys->dd_head_dataset_obj;
2895 
2896                                 VERIFY3U(zap_remove_int(dp->dp_meta_objset,
2897                                     odd->dd_phys->dd_clones, o, tx), ==, 0);
2898                                 VERIFY3U(zap_add_int(dp->dp_meta_objset,
2899                                     dd->dd_phys->dd_clones, o, tx), ==, 0);
2900                                 dsl_dataset_rele(cnds, FTAG);
2901                         }
2902                         zap_cursor_fini(&zc);
2903                 }
2904 
2905                 ASSERT3U(dsl_prop_numcb(ds), ==, 0);
2906         }
2907 
2908         /*
2909          * Change space accounting.
2910          * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
2911          * both be valid, or both be 0 (resulting in delta == 0).  This
2912          * is true for each of {clone,origin} independently.
2913          */
2914 
2915         delta = pa->cloneusedsnap -
2916             dd->dd_phys->dd_used_breakdown[DD_USED_SNAP];
2917         ASSERT3S(delta, >=, 0);
2918         ASSERT3U(pa->used, >=, delta);
2919         dsl_dir_diduse_space(dd, DD_USED_SNAP, delta, 0, 0, tx);
2920         dsl_dir_diduse_space(dd, DD_USED_HEAD,
2921             pa->used - delta, pa->comp, pa->uncomp, tx);
2922 
2923         delta = pa->originusedsnap -
2924             odd->dd_phys->dd_used_breakdown[DD_USED_SNAP];
2925         ASSERT3S(delta, <=, 0);


3590 static void
3591 dsl_dataset_user_release_onexit(void *arg)
3592 {
3593         zfs_hold_cleanup_arg_t *ca = arg;
3594 
3595         (void) dsl_dataset_user_release_tmp(ca->dp, ca->dsobj, ca->htag,
3596             B_TRUE);
3597         kmem_free(ca, sizeof (zfs_hold_cleanup_arg_t));
3598 }
3599 
3600 void
3601 dsl_register_onexit_hold_cleanup(dsl_dataset_t *ds, const char *htag,
3602     minor_t minor)
3603 {
3604         zfs_hold_cleanup_arg_t *ca;
3605 
3606         ca = kmem_alloc(sizeof (zfs_hold_cleanup_arg_t), KM_SLEEP);
3607         ca->dp = ds->ds_dir->dd_pool;
3608         ca->dsobj = ds->ds_object;
3609         (void) strlcpy(ca->htag, htag, sizeof (ca->htag));
3610         VERIFY3U(0, ==, zfs_onexit_add_cb(minor,
3611             dsl_dataset_user_release_onexit, ca, NULL));
3612 }
3613 
3614 /*
3615  * If you add new checks here, you may need to add
3616  * additional checks to the "temporary" case in
3617  * snapshot_check() in dmu_objset.c.
3618  */
3619 static int
3620 dsl_dataset_user_hold_check(void *arg1, void *arg2, dmu_tx_t *tx)
3621 {
3622         dsl_dataset_t *ds = arg1;
3623         struct dsl_ds_holdarg *ha = arg2;
3624         const char *htag = ha->htag;
3625         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
3626         int error = 0;
3627 
3628         if (spa_version(ds->ds_dir->dd_pool->dp_spa) < SPA_VERSION_USERREFS)
3629                 return (ENOTSUP);
3630 




 814         if (origin == NULL) {
 815                 dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx);
 816         } else {
 817                 dsl_dataset_t *ohds;
 818 
 819                 dsphys->ds_prev_snap_obj = origin->ds_object;
 820                 dsphys->ds_prev_snap_txg =
 821                     origin->ds_phys->ds_creation_txg;
 822                 dsphys->ds_referenced_bytes =
 823                     origin->ds_phys->ds_referenced_bytes;
 824                 dsphys->ds_compressed_bytes =
 825                     origin->ds_phys->ds_compressed_bytes;
 826                 dsphys->ds_uncompressed_bytes =
 827                     origin->ds_phys->ds_uncompressed_bytes;
 828                 dsphys->ds_bp = origin->ds_phys->ds_bp;
 829                 dsphys->ds_flags |= origin->ds_phys->ds_flags;
 830 
 831                 dmu_buf_will_dirty(origin->ds_dbuf, tx);
 832                 origin->ds_phys->ds_num_children++;
 833 
 834                 VERIFY0(dsl_dataset_hold_obj(dp,
 835                     origin->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ohds));
 836                 dsphys->ds_deadlist_obj = dsl_deadlist_clone(&ohds->ds_deadlist,
 837                     dsphys->ds_prev_snap_txg, dsphys->ds_prev_snap_obj, tx);
 838                 dsl_dataset_rele(ohds, FTAG);
 839 
 840                 if (spa_version(dp->dp_spa) >= SPA_VERSION_NEXT_CLONES) {
 841                         if (origin->ds_phys->ds_next_clones_obj == 0) {
 842                                 origin->ds_phys->ds_next_clones_obj =
 843                                     zap_create(mos,
 844                                     DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
 845                         }
 846                         VERIFY(0 == zap_add_int(mos,
 847                             origin->ds_phys->ds_next_clones_obj,
 848                             dsobj, tx));
 849                 }
 850 
 851                 dmu_buf_will_dirty(dd->dd_dbuf, tx);
 852                 dd->dd_phys->dd_origin_obj = origin->ds_object;
 853                 if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
 854                         if (origin->ds_dir->dd_phys->dd_clones == 0) {
 855                                 dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
 856                                 origin->ds_dir->dd_phys->dd_clones =
 857                                     zap_create(mos,
 858                                     DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
 859                         }
 860                         VERIFY0(zap_add_int(mos,
 861                             origin->ds_dir->dd_phys->dd_clones, dsobj, tx));
 862                 }
 863         }
 864 
 865         if (spa_version(dp->dp_spa) >= SPA_VERSION_UNIQUE_ACCURATE)
 866                 dsphys->ds_flags |= DS_FLAG_UNIQUE_ACCURATE;
 867 
 868         dmu_buf_rele(dbuf, FTAG);
 869 
 870         dmu_buf_will_dirty(dd->dd_dbuf, tx);
 871         dd->dd_phys->dd_head_dataset_obj = dsobj;
 872 
 873         return (dsobj);
 874 }
 875 
 876 uint64_t
 877 dsl_dataset_create_sync(dsl_dir_t *pdd, const char *lastname,
 878     dsl_dataset_t *origin, uint64_t flags, cred_t *cr, dmu_tx_t *tx)
 879 {
 880         dsl_pool_t *dp = pdd->dd_pool;


 883 
 884         ASSERT(lastname[0] != '@');
 885 
 886         ddobj = dsl_dir_create_sync(dp, pdd, lastname, tx);
 887         VERIFY(0 == dsl_dir_open_obj(dp, ddobj, lastname, FTAG, &dd));
 888 
 889         dsobj = dsl_dataset_create_sync_dd(dd, origin, flags, tx);
 890 
 891         dsl_deleg_set_create_perms(dd, tx, cr);
 892 
 893         dsl_dir_close(dd, FTAG);
 894 
 895         /*
 896          * If we are creating a clone, make sure we zero out any stale
 897          * data from the origin snapshots zil header.
 898          */
 899         if (origin != NULL) {
 900                 dsl_dataset_t *ds;
 901                 objset_t *os;
 902 
 903                 VERIFY0(dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
 904                 VERIFY0(dmu_objset_from_ds(ds, &os));
 905                 bzero(&os->os_zil_header, sizeof (os->os_zil_header));
 906                 dsl_dataset_dirty(ds, tx);
 907                 dsl_dataset_rele(ds, FTAG);
 908         }
 909 
 910         return (dsobj);
 911 }
 912 
 913 /*
 914  * The snapshots must all be in the same pool.
 915  */
 916 int
 917 dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer,
 918     nvlist_t *errlist)
 919 {
 920         int err;
 921         dsl_sync_task_t *dst;
 922         spa_t *spa;
 923         nvpair_t *pair;
 924         dsl_sync_task_group_t *dstg;


1487 static void
1488 remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj, dmu_tx_t *tx)
1489 {
1490         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
1491         uint64_t count;
1492         int err;
1493 
1494         ASSERT(ds->ds_phys->ds_num_children >= 2);
1495         err = zap_remove_int(mos, ds->ds_phys->ds_next_clones_obj, obj, tx);
1496         /*
1497          * The err should not be ENOENT, but a bug in a previous version
1498          * of the code could cause upgrade_clones_cb() to not set
1499          * ds_next_snap_obj when it should, leading to a missing entry.
1500          * If we knew that the pool was created after
1501          * SPA_VERSION_NEXT_CLONES, we could assert that it isn't
1502          * ENOENT.  However, at least we can check that we don't have
1503          * too many entries in the next_clones_obj even after failing to
1504          * remove this one.
1505          */
1506         if (err != ENOENT) {
1507                 VERIFY0(err);
1508         }
1509         ASSERT0(zap_count(mos, ds->ds_phys->ds_next_clones_obj, &count));

1510         ASSERT3U(count, <=, ds->ds_phys->ds_num_children - 2);
1511 }
1512 
1513 static void
1514 dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)
1515 {
1516         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
1517         zap_cursor_t zc;
1518         zap_attribute_t za;
1519 
1520         /*
1521          * If it is the old version, dd_clones doesn't exist so we can't
1522          * find the clones, but deadlist_remove_key() is a no-op so it
1523          * doesn't matter.
1524          */
1525         if (ds->ds_dir->dd_phys->dd_clones == 0)
1526                 return;
1527 
1528         for (zap_cursor_init(&zc, mos, ds->ds_dir->dd_phys->dd_clones);
1529             zap_cursor_retrieve(&zc, &za) == 0;
1530             zap_cursor_advance(&zc)) {
1531                 dsl_dataset_t *clone;
1532 
1533                 VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
1534                     za.za_first_integer, FTAG, &clone));
1535                 if (clone->ds_dir->dd_origin_txg > mintxg) {
1536                         dsl_deadlist_remove_key(&clone->ds_deadlist,
1537                             mintxg, tx);
1538                         dsl_dataset_remove_clones_key(clone, mintxg, tx);
1539                 }
1540                 dsl_dataset_rele(clone, FTAG);
1541         }
1542         zap_cursor_fini(&zc);
1543 }
1544 
1545 struct process_old_arg {
1546         dsl_dataset_t *ds;
1547         dsl_dataset_t *ds_prev;
1548         boolean_t after_branch_point;
1549         zio_t *pio;
1550         uint64_t used, comp, uncomp;
1551 };
1552 
1553 static int


1571                 dsl_free_sync(poa->pio, dp, tx->tx_txg, bp);
1572         }
1573         return (0);
1574 }
1575 
1576 static void
1577 process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
1578     dsl_dataset_t *ds_next, boolean_t after_branch_point, dmu_tx_t *tx)
1579 {
1580         struct process_old_arg poa = { 0 };
1581         dsl_pool_t *dp = ds->ds_dir->dd_pool;
1582         objset_t *mos = dp->dp_meta_objset;
1583 
1584         ASSERT(ds->ds_deadlist.dl_oldfmt);
1585         ASSERT(ds_next->ds_deadlist.dl_oldfmt);
1586 
1587         poa.ds = ds;
1588         poa.ds_prev = ds_prev;
1589         poa.after_branch_point = after_branch_point;
1590         poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
1591         VERIFY0(bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
1592             process_old_cb, &poa, tx));
1593         VERIFY0(zio_wait(poa.pio));
1594         ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
1595 
1596         /* change snapused */
1597         dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
1598             -poa.used, -poa.comp, -poa.uncomp, tx);
1599 
1600         /* swap next's deadlist to our deadlist */
1601         dsl_deadlist_close(&ds->ds_deadlist);
1602         dsl_deadlist_close(&ds_next->ds_deadlist);
1603         SWITCH64(ds_next->ds_phys->ds_deadlist_obj,
1604             ds->ds_phys->ds_deadlist_obj);
1605         dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj);
1606         dsl_deadlist_open(&ds_next->ds_deadlist, mos,
1607             ds_next->ds_phys->ds_deadlist_obj);
1608 }
1609 
1610 static int
1611 old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
1612 {
1613         int err;
1614         struct killarg ka;
1615 
1616         /*
1617          * Free everything that we point to (that's born after
1618          * the previous snapshot, if we are a clone)
1619          *
1620          * NB: this should be very quick, because we already
1621          * freed all the objects in open context.
1622          */
1623         ka.ds = ds;
1624         ka.tx = tx;
1625         err = traverse_dataset(ds,
1626             ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
1627             kill_blkptr, &ka);
1628         ASSERT0(err);
1629         ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
1630 
1631         return (err);
1632 }
1633 
1634 void
1635 dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
1636 {
1637         struct dsl_ds_destroyarg *dsda = arg1;
1638         dsl_dataset_t *ds = dsda->ds;
1639         int err;
1640         int after_branch_point = FALSE;
1641         dsl_pool_t *dp = ds->ds_dir->dd_pool;
1642         objset_t *mos = dp->dp_meta_objset;
1643         dsl_dataset_t *ds_prev = NULL;
1644         boolean_t wont_destroy;
1645         uint64_t obj;
1646 
1647         wont_destroy = (dsda->defer &&
1648             (ds->ds_userrefs > 0 || ds->ds_phys->ds_num_children > 1));


1664         /* We need to log before removing it from the namespace. */
1665         spa_history_log_internal_ds(ds, "destroy", tx, "");
1666 
1667         /* signal any waiters that this dataset is going away */
1668         mutex_enter(&ds->ds_lock);
1669         ds->ds_owner = dsl_reaper;
1670         cv_broadcast(&ds->ds_exclusive_cv);
1671         mutex_exit(&ds->ds_lock);
1672 
1673         /* Remove our reservation */
1674         if (ds->ds_reserved != 0) {
1675                 dsl_prop_setarg_t psa;
1676                 uint64_t value = 0;
1677 
1678                 dsl_prop_setarg_init_uint64(&psa, "refreservation",
1679                     (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED),
1680                     &value);
1681                 psa.psa_effective_value = 0;    /* predict default value */
1682 
1683                 dsl_dataset_set_reservation_sync(ds, &psa, tx);
1684                 ASSERT0(ds->ds_reserved);
1685         }
1686 
1687         ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock));
1688 
1689         dsl_scan_ds_destroyed(ds, tx);
1690 
1691         obj = ds->ds_object;
1692 
1693         if (ds->ds_phys->ds_prev_snap_obj != 0) {
1694                 if (ds->ds_prev) {
1695                         ds_prev = ds->ds_prev;
1696                 } else {
1697                         VERIFY(0 == dsl_dataset_hold_obj(dp,
1698                             ds->ds_phys->ds_prev_snap_obj, FTAG, &ds_prev));
1699                 }
1700                 after_branch_point =
1701                     (ds_prev->ds_phys->ds_next_snap_obj != obj);
1702 
1703                 dmu_buf_will_dirty(ds_prev->ds_dbuf, tx);
1704                 if (after_branch_point &&


1801                          * were previously shared by only this snapshot
1802                          * and it.  Those blocks will be born after the
1803                          * prev snap and before this snap, and will have
1804                          * died after the next snap and before the one
1805                          * after that (ie. be on the snap after next's
1806                          * deadlist).
1807                          */
1808                         VERIFY(0 == dsl_dataset_hold_obj(dp,
1809                             ds_next->ds_phys->ds_next_snap_obj,
1810                             FTAG, &ds_nextnext));
1811                         dsl_deadlist_space_range(&ds_nextnext->ds_deadlist,
1812                             ds->ds_phys->ds_prev_snap_txg,
1813                             ds->ds_phys->ds_creation_txg,
1814                             &used, &comp, &uncomp);
1815                         ds_next->ds_phys->ds_unique_bytes += used;
1816                         dsl_dataset_rele(ds_nextnext, FTAG);
1817                         ASSERT3P(ds_next->ds_prev, ==, NULL);
1818 
1819                         /* Collapse range in this head. */
1820                         dsl_dataset_t *hds;
1821                         VERIFY0(dsl_dataset_hold_obj(dp,
1822                             ds->ds_dir->dd_phys->dd_head_dataset_obj,
1823                             FTAG, &hds));
1824                         dsl_deadlist_remove_key(&hds->ds_deadlist,
1825                             ds->ds_phys->ds_creation_txg, tx);
1826                         dsl_dataset_rele(hds, FTAG);
1827 
1828                 } else {
1829                         ASSERT3P(ds_next->ds_prev, ==, ds);
1830                         dsl_dataset_drop_ref(ds_next->ds_prev, ds_next);
1831                         ds_next->ds_prev = NULL;
1832                         if (ds_prev) {
1833                                 VERIFY(0 == dsl_dataset_get_ref(dp,
1834                                     ds->ds_phys->ds_prev_snap_obj,
1835                                     ds_next, &ds_next->ds_prev));
1836                         }
1837 
1838                         dsl_dataset_recalc_head_uniq(ds_next);
1839 
1840                         /*
1841                          * Reduce the amount of our unconsmed refreservation


1890                         }
1891 
1892                         used = ds->ds_dir->dd_phys->dd_used_bytes;
1893                         comp = ds->ds_dir->dd_phys->dd_compressed_bytes;
1894                         uncomp = ds->ds_dir->dd_phys->dd_uncompressed_bytes;
1895 
1896                         ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
1897                             ds->ds_phys->ds_unique_bytes == used);
1898 
1899                         bptree_add(dp->dp_meta_objset, dp->dp_bptree_obj,
1900                             &ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
1901                             used, comp, uncomp, tx);
1902                         dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
1903                             -used, -comp, -uncomp, tx);
1904                         dsl_dir_diduse_space(dp->dp_free_dir, DD_USED_HEAD,
1905                             used, comp, uncomp, tx);
1906                 }
1907 
1908                 if (ds->ds_prev != NULL) {
1909                         if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
1910                                 VERIFY0(zap_remove_int(mos,
1911                                     ds->ds_prev->ds_dir->dd_phys->dd_clones,
1912                                     ds->ds_object, tx));
1913                         }
1914                         dsl_dataset_rele(ds->ds_prev, ds);
1915                         ds->ds_prev = ds_prev = NULL;
1916                 }
1917         }
1918 
1919         /*
1920          * This must be done after the dsl_traverse(), because it will
1921          * re-open the objset.
1922          */
1923         if (ds->ds_objset) {
1924                 dmu_objset_evict(ds->ds_objset);
1925                 ds->ds_objset = NULL;
1926         }
1927 
1928         if (ds->ds_dir->dd_phys->dd_head_dataset_obj == ds->ds_object) {
1929                 /* Erase the link in the dir */
1930                 dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
1931                 ds->ds_dir->dd_phys->dd_head_dataset_obj = 0;
1932                 ASSERT(ds->ds_phys->ds_snapnames_zapobj != 0);
1933                 err = zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx);
1934                 ASSERT(err == 0);
1935         } else {
1936                 /* remove from snapshot namespace */
1937                 dsl_dataset_t *ds_head;
1938                 ASSERT(ds->ds_phys->ds_snapnames_zapobj == 0);
1939                 VERIFY(0 == dsl_dataset_hold_obj(dp,
1940                     ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head));
1941                 VERIFY(0 == dsl_dataset_get_snapname(ds));
1942 #ifdef ZFS_DEBUG
1943                 {
1944                         uint64_t val;
1945 
1946                         err = dsl_dataset_snap_lookup(ds_head,
1947                             ds->ds_snapname, &val);
1948                         ASSERT0(err);
1949                         ASSERT3U(val, ==, obj);
1950                 }
1951 #endif
1952                 err = dsl_dataset_snap_remove(ds_head, ds->ds_snapname, tx);
1953                 ASSERT(err == 0);
1954                 dsl_dataset_rele(ds_head, FTAG);
1955         }
1956 
1957         if (ds_prev && ds->ds_prev != ds_prev)
1958                 dsl_dataset_rele(ds_prev, FTAG);
1959 
1960         spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
1961 
1962         if (ds->ds_phys->ds_next_clones_obj != 0) {
1963                 uint64_t count;
1964                 ASSERT(0 == zap_count(mos,
1965                     ds->ds_phys->ds_next_clones_obj, &count) && count == 0);
1966                 VERIFY(0 == dmu_object_free(mos,
1967                     ds->ds_phys->ds_next_clones_obj, tx));
1968         }


2095         dsphys->ds_uncompressed_bytes = ds->ds_phys->ds_uncompressed_bytes;
2096         dsphys->ds_flags = ds->ds_phys->ds_flags;
2097         dsphys->ds_bp = ds->ds_phys->ds_bp;
2098         dmu_buf_rele(dbuf, FTAG);
2099 
2100         ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0);
2101         if (ds->ds_prev) {
2102                 uint64_t next_clones_obj =
2103                     ds->ds_prev->ds_phys->ds_next_clones_obj;
2104                 ASSERT(ds->ds_prev->ds_phys->ds_next_snap_obj ==
2105                     ds->ds_object ||
2106                     ds->ds_prev->ds_phys->ds_num_children > 1);
2107                 if (ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object) {
2108                         dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
2109                         ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==,
2110                             ds->ds_prev->ds_phys->ds_creation_txg);
2111                         ds->ds_prev->ds_phys->ds_next_snap_obj = dsobj;
2112                 } else if (next_clones_obj != 0) {
2113                         remove_from_next_clones(ds->ds_prev,
2114                             dsphys->ds_next_snap_obj, tx);
2115                         VERIFY0(zap_add_int(mos,
2116                             next_clones_obj, dsobj, tx));
2117                 }
2118         }
2119 
2120         /*
2121          * If we have a reference-reservation on this dataset, we will
2122          * need to increase the amount of refreservation being charged
2123          * since our unique space is going to zero.
2124          */
2125         if (ds->ds_reserved) {
2126                 int64_t delta;
2127                 ASSERT(DS_UNIQUE_IS_ACCURATE(ds));
2128                 delta = MIN(ds->ds_phys->ds_unique_bytes, ds->ds_reserved);
2129                 dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV,
2130                     delta, 0, 0, tx);
2131         }
2132 
2133         dmu_buf_will_dirty(ds->ds_dbuf, tx);
2134         zfs_dbgmsg("taking snapshot %s@%s/%llu; newkey=%llu",
2135             ds->ds_dir->dd_myname, snapname, dsobj,


2185 static void
2186 get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
2187 {
2188         uint64_t count = 0;
2189         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
2190         zap_cursor_t zc;
2191         zap_attribute_t za;
2192         nvlist_t *propval;
2193         nvlist_t *val;
2194 
2195         rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
2196         VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2197         VERIFY(nvlist_alloc(&val, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2198 
2199         /*
2200          * There may me missing entries in ds_next_clones_obj
2201          * due to a bug in a previous version of the code.
2202          * Only trust it if it has the right number of entries.
2203          */
2204         if (ds->ds_phys->ds_next_clones_obj != 0) {
2205                 ASSERT0(zap_count(mos, ds->ds_phys->ds_next_clones_obj,
2206                     &count));
2207         }
2208         if (count != ds->ds_phys->ds_num_children - 1) {
2209                 goto fail;
2210         }
2211         for (zap_cursor_init(&zc, mos, ds->ds_phys->ds_next_clones_obj);
2212             zap_cursor_retrieve(&zc, &za) == 0;
2213             zap_cursor_advance(&zc)) {
2214                 dsl_dataset_t *clone;
2215                 char buf[ZFS_MAXNAMELEN];
2216                 /*
2217                  * Even though we hold the dp_config_rwlock, the dataset
2218                  * may fail to open, returning ENOENT.  If there is a
2219                  * thread concurrently attempting to destroy this
2220                  * dataset, it will have the ds_rwlock held for
2221                  * RW_WRITER.  Our call to dsl_dataset_hold_obj() ->
2222                  * dsl_dataset_hold_ref() will fail its
2223                  * rw_tryenter(&ds->ds_rwlock, RW_READER), drop the
2224                  * dp_config_rwlock, and wait for the destroy progress
2225                  * and signal ds_exclusive_cv.  If the destroy was


2424         return (err);
2425 }
2426 
2427 static void
2428 dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
2429 {
2430         dsl_dataset_t *ds = arg1;
2431         const char *newsnapname = arg2;
2432         dsl_dir_t *dd = ds->ds_dir;
2433         objset_t *mos = dd->dd_pool->dp_meta_objset;
2434         dsl_dataset_t *hds;
2435         int err;
2436 
2437         ASSERT(ds->ds_phys->ds_next_snap_obj != 0);
2438 
2439         VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool,
2440             dd->dd_phys->dd_head_dataset_obj, FTAG, &hds));
2441 
2442         VERIFY(0 == dsl_dataset_get_snapname(ds));
2443         err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
2444         ASSERT0(err);
2445         mutex_enter(&ds->ds_lock);
2446         (void) strcpy(ds->ds_snapname, newsnapname);
2447         mutex_exit(&ds->ds_lock);
2448         err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
2449             ds->ds_snapname, 8, 1, &ds->ds_object, tx);
2450         ASSERT0(err);
2451 
2452         spa_history_log_internal_ds(ds, "rename", tx,
2453             "-> @%s", newsnapname);
2454         dsl_dataset_rele(hds, FTAG);
2455 }
2456 
2457 struct renamesnaparg {
2458         dsl_sync_task_group_t *dstg;
2459         char failed[MAXPATHLEN];
2460         char *oldsnap;
2461         char *newsnap;
2462 };
2463 
2464 static int
2465 dsl_snapshot_rename_one(const char *name, void *arg)
2466 {
2467         struct renamesnaparg *ra = arg;
2468         dsl_dataset_t *ds = NULL;
2469         char *snapname;
2470         int err;


2788         snap = list_head(&pa->origin_snaps);
2789         origin_head = snap->ds;
2790 
2791         /*
2792          * We need to explicitly open odd, since origin_ds's dd will be
2793          * changing.
2794          */
2795         VERIFY(0 == dsl_dir_open_obj(dp, origin_ds->ds_dir->dd_object,
2796             NULL, FTAG, &odd));
2797 
2798         /* change origin's next snap */
2799         dmu_buf_will_dirty(origin_ds->ds_dbuf, tx);
2800         oldnext_obj = origin_ds->ds_phys->ds_next_snap_obj;
2801         snap = list_tail(&pa->clone_snaps);
2802         ASSERT3U(snap->ds->ds_phys->ds_prev_snap_obj, ==, origin_ds->ds_object);
2803         origin_ds->ds_phys->ds_next_snap_obj = snap->ds->ds_object;
2804 
2805         /* change the origin's next clone */
2806         if (origin_ds->ds_phys->ds_next_clones_obj) {
2807                 remove_from_next_clones(origin_ds, snap->ds->ds_object, tx);
2808                 VERIFY0(zap_add_int(dp->dp_meta_objset,
2809                     origin_ds->ds_phys->ds_next_clones_obj,
2810                     oldnext_obj, tx));
2811         }
2812 
2813         /* change origin */
2814         dmu_buf_will_dirty(dd->dd_dbuf, tx);
2815         ASSERT3U(dd->dd_phys->dd_origin_obj, ==, origin_ds->ds_object);
2816         dd->dd_phys->dd_origin_obj = odd->dd_phys->dd_origin_obj;
2817         dd->dd_origin_txg = origin_head->ds_dir->dd_origin_txg;
2818         dmu_buf_will_dirty(odd->dd_dbuf, tx);
2819         odd->dd_phys->dd_origin_obj = origin_ds->ds_object;
2820         origin_head->ds_dir->dd_origin_txg =
2821             origin_ds->ds_phys->ds_creation_txg;
2822 
2823         /* change dd_clone entries */
2824         if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
2825                 VERIFY0(zap_remove_int(dp->dp_meta_objset,
2826                     odd->dd_phys->dd_clones, hds->ds_object, tx));
2827                 VERIFY0(zap_add_int(dp->dp_meta_objset,
2828                     pa->origin_origin->ds_dir->dd_phys->dd_clones,
2829                     hds->ds_object, tx));
2830 
2831                 VERIFY0(zap_remove_int(dp->dp_meta_objset,
2832                     pa->origin_origin->ds_dir->dd_phys->dd_clones,
2833                     origin_head->ds_object, tx));
2834                 if (dd->dd_phys->dd_clones == 0) {
2835                         dd->dd_phys->dd_clones = zap_create(dp->dp_meta_objset,
2836                             DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
2837                 }
2838                 VERIFY0(zap_add_int(dp->dp_meta_objset,
2839                     dd->dd_phys->dd_clones, origin_head->ds_object, tx));
2840 
2841         }
2842 
2843         /* move snapshots to this dir */
2844         for (snap = list_head(&pa->shared_snaps); snap;
2845             snap = list_next(&pa->shared_snaps, snap)) {
2846                 dsl_dataset_t *ds = snap->ds;
2847 
2848                 /* unregister props as dsl_dir is changing */
2849                 if (ds->ds_objset) {
2850                         dmu_objset_evict(ds->ds_objset);
2851                         ds->ds_objset = NULL;
2852                 }
2853                 /* move snap name entry */
2854                 VERIFY(0 == dsl_dataset_get_snapname(ds));
2855                 VERIFY(0 == dsl_dataset_snap_remove(origin_head,
2856                     ds->ds_snapname, tx));
2857                 VERIFY(0 == zap_add(dp->dp_meta_objset,
2858                     hds->ds_phys->ds_snapnames_zapobj, ds->ds_snapname,


2871                 if (ds->ds_phys->ds_next_clones_obj &&
2872                     spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
2873                         zap_cursor_t zc;
2874                         zap_attribute_t za;
2875 
2876                         for (zap_cursor_init(&zc, dp->dp_meta_objset,
2877                             ds->ds_phys->ds_next_clones_obj);
2878                             zap_cursor_retrieve(&zc, &za) == 0;
2879                             zap_cursor_advance(&zc)) {
2880                                 dsl_dataset_t *cnds;
2881                                 uint64_t o;
2882 
2883                                 if (za.za_first_integer == oldnext_obj) {
2884                                         /*
2885                                          * We've already moved the
2886                                          * origin's reference.
2887                                          */
2888                                         continue;
2889                                 }
2890 
2891                                 VERIFY0(dsl_dataset_hold_obj(dp,
2892                                     za.za_first_integer, FTAG, &cnds));
2893                                 o = cnds->ds_dir->dd_phys->dd_head_dataset_obj;
2894 
2895                                 VERIFY3U(zap_remove_int(dp->dp_meta_objset,
2896                                     odd->dd_phys->dd_clones, o, tx), ==, 0);
2897                                 VERIFY3U(zap_add_int(dp->dp_meta_objset,
2898                                     dd->dd_phys->dd_clones, o, tx), ==, 0);
2899                                 dsl_dataset_rele(cnds, FTAG);
2900                         }
2901                         zap_cursor_fini(&zc);
2902                 }
2903 
2904                 ASSERT0(dsl_prop_numcb(ds));
2905         }
2906 
2907         /*
2908          * Change space accounting.
2909          * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either
2910          * both be valid, or both be 0 (resulting in delta == 0).  This
2911          * is true for each of {clone,origin} independently.
2912          */
2913 
2914         delta = pa->cloneusedsnap -
2915             dd->dd_phys->dd_used_breakdown[DD_USED_SNAP];
2916         ASSERT3S(delta, >=, 0);
2917         ASSERT3U(pa->used, >=, delta);
2918         dsl_dir_diduse_space(dd, DD_USED_SNAP, delta, 0, 0, tx);
2919         dsl_dir_diduse_space(dd, DD_USED_HEAD,
2920             pa->used - delta, pa->comp, pa->uncomp, tx);
2921 
2922         delta = pa->originusedsnap -
2923             odd->dd_phys->dd_used_breakdown[DD_USED_SNAP];
2924         ASSERT3S(delta, <=, 0);


3589 static void
3590 dsl_dataset_user_release_onexit(void *arg)
3591 {
3592         zfs_hold_cleanup_arg_t *ca = arg;
3593 
3594         (void) dsl_dataset_user_release_tmp(ca->dp, ca->dsobj, ca->htag,
3595             B_TRUE);
3596         kmem_free(ca, sizeof (zfs_hold_cleanup_arg_t));
3597 }
3598 
3599 void
3600 dsl_register_onexit_hold_cleanup(dsl_dataset_t *ds, const char *htag,
3601     minor_t minor)
3602 {
3603         zfs_hold_cleanup_arg_t *ca;
3604 
3605         ca = kmem_alloc(sizeof (zfs_hold_cleanup_arg_t), KM_SLEEP);
3606         ca->dp = ds->ds_dir->dd_pool;
3607         ca->dsobj = ds->ds_object;
3608         (void) strlcpy(ca->htag, htag, sizeof (ca->htag));
3609         VERIFY0(zfs_onexit_add_cb(minor,
3610             dsl_dataset_user_release_onexit, ca, NULL));
3611 }
3612 
3613 /*
3614  * If you add new checks here, you may need to add
3615  * additional checks to the "temporary" case in
3616  * snapshot_check() in dmu_objset.c.
3617  */
3618 static int
3619 dsl_dataset_user_hold_check(void *arg1, void *arg2, dmu_tx_t *tx)
3620 {
3621         dsl_dataset_t *ds = arg1;
3622         struct dsl_ds_holdarg *ha = arg2;
3623         const char *htag = ha->htag;
3624         objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
3625         int error = 0;
3626 
3627         if (spa_version(ds->ds_dir->dd_pool->dp_spa) < SPA_VERSION_USERREFS)
3628                 return (ENOTSUP);
3629