dsl_dataset.c (5094:71a3e95fb9e2) | dsl_dataset.c (5326:6752aa2bd5bc) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 1521 unchanged lines hidden (view full) --- 1530 uint64_t *usedobjsp, uint64_t *availobjsp) 1531{ 1532 *refdbytesp = ds->ds_phys->ds_used_bytes; 1533 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE); 1534 *usedobjsp = ds->ds_phys->ds_bp.blk_fill; 1535 *availobjsp = DN_MAX_OBJECT - *usedobjsp; 1536} 1537 | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 1521 unchanged lines hidden (view full) --- 1530 uint64_t *usedobjsp, uint64_t *availobjsp) 1531{ 1532 *refdbytesp = ds->ds_phys->ds_used_bytes; 1533 *availbytesp = dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE); 1534 *usedobjsp = ds->ds_phys->ds_bp.blk_fill; 1535 *availobjsp = DN_MAX_OBJECT - *usedobjsp; 1536} 1537 |
1538boolean_t 1539dsl_dataset_modified_since_lastsnap(dsl_dataset_t *ds) 1540{ 1541 dsl_pool_t *dp = ds->ds_dir->dd_pool; 1542 1543 ASSERT(RW_LOCK_HELD(&dp->dp_config_rwlock) || 1544 dsl_pool_sync_context(dp)); 1545 if (ds->ds_prev == NULL) 1546 return (B_FALSE); 1547 if (ds->ds_phys->ds_bp.blk_birth > 1548 ds->ds_prev->ds_phys->ds_creation_txg) 1549 return (B_TRUE); 1550 return (B_FALSE); 1551} 1552 |
|
1538/* ARGSUSED */ 1539static int 1540dsl_dataset_snapshot_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) 1541{ 1542 dsl_dataset_t *ds = arg1; 1543 char *newsnapname = arg2; 1544 dsl_dir_t *dd = ds->ds_dir; 1545 objset_t *mos = dd->dd_pool->dp_meta_objset; --- 50 unchanged lines hidden (view full) --- 1596 ds->ds_snapname, 8, 1, &ds->ds_object, tx); 1597 ASSERT3U(err, ==, 0); 1598 1599 spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, 1600 cr, "dataset = %llu", ds->ds_object); 1601 dsl_dataset_close(hds, DS_MODE_NONE, FTAG); 1602} 1603 | 1553/* ARGSUSED */ 1554static int 1555dsl_dataset_snapshot_rename_check(void *arg1, void *arg2, dmu_tx_t *tx) 1556{ 1557 dsl_dataset_t *ds = arg1; 1558 char *newsnapname = arg2; 1559 dsl_dir_t *dd = ds->ds_dir; 1560 objset_t *mos = dd->dd_pool->dp_meta_objset; --- 50 unchanged lines hidden (view full) --- 1611 ds->ds_snapname, 8, 1, &ds->ds_object, tx); 1612 ASSERT3U(err, ==, 0); 1613 1614 spa_history_internal_log(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, 1615 cr, "dataset = %llu", ds->ds_object); 1616 dsl_dataset_close(hds, DS_MODE_NONE, FTAG); 1617} 1618 |
1604struct renamearg { | 1619struct renamesnaparg { |
1605 dsl_sync_task_group_t *dstg; 1606 char failed[MAXPATHLEN]; 1607 char *oldsnap; 1608 char *newsnap; 1609}; 1610 1611static int 1612dsl_snapshot_rename_one(char *name, void *arg) 1613{ | 1620 dsl_sync_task_group_t *dstg; 1621 char failed[MAXPATHLEN]; 1622 char *oldsnap; 1623 char *newsnap; 1624}; 1625 1626static int 1627dsl_snapshot_rename_one(char *name, void *arg) 1628{ |
1614 struct renamearg *ra = arg; | 1629 struct renamesnaparg *ra = arg; |
1615 dsl_dataset_t *ds = NULL; 1616 char *cp; 1617 int err; 1618 1619 cp = name + strlen(name); 1620 *cp = '@'; 1621 (void) strcpy(cp + 1, ra->oldsnap); 1622 --- 31 unchanged lines hidden (view full) --- 1654 1655 return (0); 1656} 1657 1658static int 1659dsl_recursive_rename(char *oldname, const char *newname) 1660{ 1661 int err; | 1630 dsl_dataset_t *ds = NULL; 1631 char *cp; 1632 int err; 1633 1634 cp = name + strlen(name); 1635 *cp = '@'; 1636 (void) strcpy(cp + 1, ra->oldsnap); 1637 --- 31 unchanged lines hidden (view full) --- 1669 1670 return (0); 1671} 1672 1673static int 1674dsl_recursive_rename(char *oldname, const char *newname) 1675{ 1676 int err; |
1662 struct renamearg *ra; | 1677 struct renamesnaparg *ra; |
1663 dsl_sync_task_t *dst; 1664 spa_t *spa; 1665 char *cp, *fsname = spa_strdup(oldname); 1666 int len = strlen(oldname); 1667 1668 /* truncate the snapshot name to get the fsname */ 1669 cp = strchr(fsname, '@'); 1670 *cp = '\0'; 1671 1672 err = spa_open(fsname, &spa, FTAG); 1673 if (err) { 1674 kmem_free(fsname, len + 1); 1675 return (err); 1676 } | 1678 dsl_sync_task_t *dst; 1679 spa_t *spa; 1680 char *cp, *fsname = spa_strdup(oldname); 1681 int len = strlen(oldname); 1682 1683 /* truncate the snapshot name to get the fsname */ 1684 cp = strchr(fsname, '@'); 1685 *cp = '\0'; 1686 1687 err = spa_open(fsname, &spa, FTAG); 1688 if (err) { 1689 kmem_free(fsname, len + 1); 1690 return (err); 1691 } |
1677 ra = kmem_alloc(sizeof (struct renamearg), KM_SLEEP); | 1692 ra = kmem_alloc(sizeof (struct renamesnaparg), KM_SLEEP); |
1678 ra->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); 1679 1680 ra->oldsnap = strchr(oldname, '@') + 1; 1681 ra->newsnap = strchr(newname, '@') + 1; 1682 *ra->failed = '\0'; 1683 1684 err = dmu_objset_find(fsname, dsl_snapshot_rename_one, ra, 1685 DS_FIND_CHILDREN); --- 13 unchanged lines hidden (view full) --- 1699 } 1700 dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); 1701 } 1702 1703 if (err) 1704 (void) strcpy(oldname, ra->failed); 1705 1706 dsl_sync_task_group_destroy(ra->dstg); | 1693 ra->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); 1694 1695 ra->oldsnap = strchr(oldname, '@') + 1; 1696 ra->newsnap = strchr(newname, '@') + 1; 1697 *ra->failed = '\0'; 1698 1699 err = dmu_objset_find(fsname, dsl_snapshot_rename_one, ra, 1700 DS_FIND_CHILDREN); --- 13 unchanged lines hidden (view full) --- 1714 } 1715 dsl_dataset_close(ds, DS_MODE_STANDARD, ra->dstg); 1716 } 1717 1718 if (err) 1719 (void) strcpy(oldname, ra->failed); 1720 1721 dsl_sync_task_group_destroy(ra->dstg); |
1707 kmem_free(ra, sizeof (struct renamearg)); | 1722 kmem_free(ra, sizeof (struct renamesnaparg)); |
1708 spa_close(spa, FTAG); 1709 return (err); 1710} 1711 1712static int 1713dsl_valid_rename(char *oldname, void *arg) 1714{ 1715 int delta = *(int *)arg; --- 330 unchanged lines hidden (view full) --- 2046 */ 2047 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 2048 dsl_dataset_promote_check, 2049 dsl_dataset_promote_sync, ds, &pa, 2 + 2 * doi.doi_physical_blks); 2050 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 2051 return (err); 2052} 2053 | 1723 spa_close(spa, FTAG); 1724 return (err); 1725} 1726 1727static int 1728dsl_valid_rename(char *oldname, void *arg) 1729{ 1730 int delta = *(int *)arg; --- 330 unchanged lines hidden (view full) --- 2061 */ 2062 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 2063 dsl_dataset_promote_check, 2064 dsl_dataset_promote_sync, ds, &pa, 2 + 2 * doi.doi_physical_blks); 2065 dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 2066 return (err); 2067} 2068 |
2069#define SWITCH64(x, y) \ 2070 { \ 2071 uint64_t __tmp = (x); \ 2072 (x) = (y); \ 2073 (y) = __tmp; \ 2074 } 2075 2076/* ARGSUSED */ 2077static int 2078dsl_dataset_clone_swap_check(void *arg1, void *arg2, dmu_tx_t *tx) 2079{ 2080 dsl_dataset_t *cds = arg1; /* clone to become new head */ 2081 boolean_t *forcep = arg2; 2082 dsl_dir_t *cdd = cds->ds_dir; 2083 dsl_pool_t *dp = cds->ds_dir->dd_pool; 2084 dsl_dataset_t *ods; /* the snapshot cds is cloned off of */ 2085 dsl_dataset_t *ohds = NULL; 2086 dsl_dir_t *odd; 2087 int err; 2088 2089 /* check that it is a clone */ 2090 if (cdd->dd_phys->dd_clone_parent_obj == 0) 2091 return (EINVAL); 2092 2093 /* check that cds is not a snapshot */ 2094 if (dsl_dataset_is_snapshot(cds)) 2095 return (EINVAL); 2096 2097 /* open the origin */ 2098 if (err = dsl_dataset_open_obj(dp, cdd->dd_phys->dd_clone_parent_obj, 2099 NULL, DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ods)) 2100 return (err); 2101 odd = ods->ds_dir; 2102 2103 /* make sure the clone is descendant of origin */ 2104 if (cdd->dd_parent != odd) { 2105 err = EINVAL; 2106 goto out; 2107 } 2108 2109 /* check that there are no snapshots after the origin */ 2110 if (cds->ds_phys->ds_prev_snap_obj != ods->ds_object || 2111 ods->ds_phys->ds_next_snap_obj != 2112 odd->dd_phys->dd_head_dataset_obj) { 2113 err = EINVAL; 2114 goto out; 2115 } 2116 2117 /* 2118 * Verify origin head dataset hasn't been modified or 2119 * 'force' has been passed down. 2120 */ 2121 if (!(*forcep) && 2122 (err = dsl_dataset_open_obj(cdd->dd_pool, 2123 odd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_EXCLUSIVE, 2124 FTAG, &ohds)) == 0) { 2125 if (dsl_dataset_modified_since_lastsnap(ohds)) 2126 err = ETXTBSY; 2127 dsl_dataset_close(ohds, DS_MODE_EXCLUSIVE, FTAG); 2128 } 2129out: 2130 dsl_dataset_close(ods, DS_MODE_STANDARD, FTAG); 2131 return (err); 2132} 2133 2134/* ARGSUSED */ 2135static void 2136dsl_dataset_clone_swap_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) 2137{ 2138 dsl_dataset_t *cds = arg1; /* clone to become new head */ 2139 dsl_dir_t *cdd = cds->ds_dir; 2140 dsl_pool_t *dp = cds->ds_dir->dd_pool; 2141 dsl_dataset_t *ods, *ohds; 2142 dsl_dir_t *odd; 2143 uint64_t itor = 0; 2144 blkptr_t bp; 2145 uint64_t unique = 0; 2146 int err; 2147 2148 ASSERT(cdd->dd_phys->dd_clone_parent_obj != 0); 2149 ASSERT(dsl_dataset_is_snapshot(cds) == 0); 2150 2151 /* open the origin */ 2152 VERIFY(0 == dsl_dataset_open_obj(dp, cdd->dd_phys->dd_clone_parent_obj, 2153 NULL, DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ods)); 2154 odd = ods->ds_dir; 2155 ASSERT(cds->ds_phys->ds_prev_snap_obj == ods->ds_object); 2156 ASSERT(ods->ds_phys->ds_next_snap_obj == 2157 odd->dd_phys->dd_head_dataset_obj); 2158 2159 /* open the origin head */ 2160 VERIFY(0 == dsl_dataset_open_obj(cdd->dd_pool, 2161 odd->dd_phys->dd_head_dataset_obj, NULL, DS_MODE_EXCLUSIVE, 2162 FTAG, &ohds)); 2163 ASSERT(odd == ohds->ds_dir); 2164 2165 dmu_buf_will_dirty(cds->ds_dbuf, tx); 2166 dmu_buf_will_dirty(ohds->ds_dbuf, tx); 2167 dmu_buf_will_dirty(ods->ds_dbuf, tx); 2168 2169 /* compute unique space */ 2170 while ((err = bplist_iterate(&cds->ds_deadlist, &itor, &bp)) == 0) { 2171 if (bp.blk_birth > ods->ds_phys->ds_prev_snap_txg) 2172 unique += bp_get_dasize(cdd->dd_pool->dp_spa, &bp); 2173 } 2174 VERIFY(err == ENOENT); 2175 2176 /* reset origin's unique bytes */ 2177 ods->ds_phys->ds_unique_bytes = unique; 2178 2179 /* swap blkptrs */ 2180 { 2181 blkptr_t tmp; 2182 tmp = ohds->ds_phys->ds_bp; 2183 ohds->ds_phys->ds_bp = cds->ds_phys->ds_bp; 2184 cds->ds_phys->ds_bp = tmp; 2185 } 2186 2187 /* set dd_*_bytes */ 2188 { 2189 int64_t dused, dcomp, duncomp; 2190 uint64_t cdl_used, cdl_comp, cdl_uncomp; 2191 uint64_t odl_used, odl_comp, odl_uncomp; 2192 2193 VERIFY(0 == bplist_space(&cds->ds_deadlist, &cdl_used, 2194 &cdl_comp, &cdl_uncomp)); 2195 VERIFY(0 == bplist_space(&ohds->ds_deadlist, &odl_used, 2196 &odl_comp, &odl_uncomp)); 2197 dused = cds->ds_phys->ds_used_bytes + cdl_used - 2198 (ohds->ds_phys->ds_used_bytes + odl_used); 2199 dcomp = cds->ds_phys->ds_compressed_bytes + cdl_comp - 2200 (ohds->ds_phys->ds_compressed_bytes + odl_comp); 2201 duncomp = cds->ds_phys->ds_uncompressed_bytes + cdl_uncomp - 2202 (ohds->ds_phys->ds_uncompressed_bytes + odl_uncomp); 2203 2204 dsl_dir_diduse_space(odd, dused, dcomp, duncomp, tx); 2205 dsl_dir_diduse_space(cdd, -dused, -dcomp, -duncomp, tx); 2206 } 2207 2208 /* swap ds_*_bytes */ 2209 SWITCH64(ohds->ds_phys->ds_used_bytes, cds->ds_phys->ds_used_bytes); 2210 SWITCH64(ohds->ds_phys->ds_compressed_bytes, 2211 cds->ds_phys->ds_compressed_bytes); 2212 SWITCH64(ohds->ds_phys->ds_uncompressed_bytes, 2213 cds->ds_phys->ds_uncompressed_bytes); 2214 2215 /* swap deadlists */ 2216 bplist_close(&cds->ds_deadlist); 2217 bplist_close(&ohds->ds_deadlist); 2218 SWITCH64(ohds->ds_phys->ds_deadlist_obj, cds->ds_phys->ds_deadlist_obj); 2219 VERIFY(0 == bplist_open(&cds->ds_deadlist, dp->dp_meta_objset, 2220 cds->ds_phys->ds_deadlist_obj)); 2221 VERIFY(0 == bplist_open(&ohds->ds_deadlist, dp->dp_meta_objset, 2222 ohds->ds_phys->ds_deadlist_obj)); 2223 2224 dsl_dataset_close(ohds, DS_MODE_EXCLUSIVE, FTAG); 2225 dsl_dataset_close(ods, DS_MODE_STANDARD, FTAG); 2226} 2227 |
|
2054/* | 2228/* |
2229 * Swap the clone "cosname" with its origin head file system. 2230 */ 2231int 2232dsl_dataset_clone_swap(const char *cosname, boolean_t force) 2233{ 2234 dsl_dataset_t *ds; 2235 int err; 2236 2237 err = dsl_dataset_open(cosname, 2238 DS_MODE_EXCLUSIVE | DS_MODE_INCONSISTENT, FTAG, &ds); 2239 if (err) 2240 return (err); 2241 2242 err = dsl_sync_task_do(ds->ds_dir->dd_pool, 2243 dsl_dataset_clone_swap_check, 2244 dsl_dataset_clone_swap_sync, ds, &force, 9); 2245 dsl_dataset_close(ds, DS_MODE_EXCLUSIVE, FTAG); 2246 return (err); 2247} 2248 2249/* |
|
2055 * Given a pool name and a dataset object number in that pool, 2056 * return the name of that dataset. 2057 */ 2058int 2059dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf) 2060{ 2061 spa_t *spa; 2062 dsl_pool_t *dp; --- 20 unchanged lines hidden --- | 2250 * Given a pool name and a dataset object number in that pool, 2251 * return the name of that dataset. 2252 */ 2253int 2254dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf) 2255{ 2256 spa_t *spa; 2257 dsl_pool_t *dp; --- 20 unchanged lines hidden --- |