1705
1706 if (owner != NULL) {
1707 VERIFY3P(ds->ds_owner, ==, owner);
1708 dsl_dataset_long_rele(ds, owner);
1709 }
1710
1711 held = dsl_dataset_long_held(ds);
1712
1713 if (owner != NULL)
1714 dsl_dataset_long_hold(ds, owner);
1715
1716 if (held)
1717 return (SET_ERROR(EBUSY));
1718
1719 return (0);
1720 }
1721
1722 typedef struct dsl_dataset_rollback_arg {
1723 const char *ddra_fsname;
1724 void *ddra_owner;
1725 } dsl_dataset_rollback_arg_t;
1726
1727 static int
1728 dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
1729 {
1730 dsl_dataset_rollback_arg_t *ddra = arg;
1731 dsl_pool_t *dp = dmu_tx_pool(tx);
1732 dsl_dataset_t *ds;
1733 int64_t unused_refres_delta;
1734 int error;
1735
1736 error = dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds);
1737 if (error != 0)
1738 return (error);
1739
1740 /* must not be a snapshot */
1741 if (dsl_dataset_is_snapshot(ds)) {
1742 dsl_dataset_rele(ds, FTAG);
1743 return (SET_ERROR(EINVAL));
1744 }
1776 ds->ds_phys->ds_unique_bytes);
1777
1778 if (unused_refres_delta > 0 &&
1779 unused_refres_delta >
1780 dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) {
1781 dsl_dataset_rele(ds, FTAG);
1782 return (SET_ERROR(ENOSPC));
1783 }
1784
1785 dsl_dataset_rele(ds, FTAG);
1786 return (0);
1787 }
1788
1789 static void
1790 dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
1791 {
1792 dsl_dataset_rollback_arg_t *ddra = arg;
1793 dsl_pool_t *dp = dmu_tx_pool(tx);
1794 dsl_dataset_t *ds, *clone;
1795 uint64_t cloneobj;
1796
1797 VERIFY0(dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds));
1798
1799 cloneobj = dsl_dataset_create_sync(ds->ds_dir, "%rollback",
1800 ds->ds_prev, DS_CREATE_FLAG_NODIRTY, kcred, tx);
1801
1802 VERIFY0(dsl_dataset_hold_obj(dp, cloneobj, FTAG, &clone));
1803
1804 dsl_dataset_clone_swap_sync_impl(clone, ds, tx);
1805 dsl_dataset_zero_zil(ds, tx);
1806
1807 dsl_destroy_head_sync_impl(clone, tx);
1808
1809 dsl_dataset_rele(clone, FTAG);
1810 dsl_dataset_rele(ds, FTAG);
1811 }
1812
1813 /*
1814 * If owner != NULL:
1815 *
1816 * - The existing dataset MUST be owned by the specified owner at entry
1817 * - Upon return, dataset will still be held by the same owner, whether we
1818 * succeed or not.
1819 *
1820 * This mode is required any time the existing filesystem is mounted. See
1821 * notes above zfs_suspend_fs() for further details.
1822 */
1823 int
1824 dsl_dataset_rollback(const char *fsname, void *owner)
1825 {
1826 dsl_dataset_rollback_arg_t ddra;
1827
1828 ddra.ddra_fsname = fsname;
1829 ddra.ddra_owner = owner;
1830
1831 return (dsl_sync_task(fsname, dsl_dataset_rollback_check,
1832 dsl_dataset_rollback_sync, (void *)&ddra, 1));
1833 }
1834
1835 struct promotenode {
1836 list_node_t link;
1837 dsl_dataset_t *ds;
1838 };
1839
1840 typedef struct dsl_dataset_promote_arg {
1841 const char *ddpa_clonename;
1842 dsl_dataset_t *ddpa_clone;
1843 list_t shared_snaps, origin_snaps, clone_snaps;
1844 dsl_dataset_t *origin_origin; /* origin of the origin */
1845 uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap;
1846 char *err_ds;
1847 } dsl_dataset_promote_arg_t;
1848
1849 static int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep);
1850 static int promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp,
1851 void *tag);
1852 static void promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag);
|
1705
1706 if (owner != NULL) {
1707 VERIFY3P(ds->ds_owner, ==, owner);
1708 dsl_dataset_long_rele(ds, owner);
1709 }
1710
1711 held = dsl_dataset_long_held(ds);
1712
1713 if (owner != NULL)
1714 dsl_dataset_long_hold(ds, owner);
1715
1716 if (held)
1717 return (SET_ERROR(EBUSY));
1718
1719 return (0);
1720 }
1721
1722 typedef struct dsl_dataset_rollback_arg {
1723 const char *ddra_fsname;
1724 void *ddra_owner;
1725 nvlist_t *ddra_result;
1726 } dsl_dataset_rollback_arg_t;
1727
1728 static int
1729 dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
1730 {
1731 dsl_dataset_rollback_arg_t *ddra = arg;
1732 dsl_pool_t *dp = dmu_tx_pool(tx);
1733 dsl_dataset_t *ds;
1734 int64_t unused_refres_delta;
1735 int error;
1736
1737 error = dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds);
1738 if (error != 0)
1739 return (error);
1740
1741 /* must not be a snapshot */
1742 if (dsl_dataset_is_snapshot(ds)) {
1743 dsl_dataset_rele(ds, FTAG);
1744 return (SET_ERROR(EINVAL));
1745 }
1777 ds->ds_phys->ds_unique_bytes);
1778
1779 if (unused_refres_delta > 0 &&
1780 unused_refres_delta >
1781 dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) {
1782 dsl_dataset_rele(ds, FTAG);
1783 return (SET_ERROR(ENOSPC));
1784 }
1785
1786 dsl_dataset_rele(ds, FTAG);
1787 return (0);
1788 }
1789
1790 static void
1791 dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
1792 {
1793 dsl_dataset_rollback_arg_t *ddra = arg;
1794 dsl_pool_t *dp = dmu_tx_pool(tx);
1795 dsl_dataset_t *ds, *clone;
1796 uint64_t cloneobj;
1797 char namebuf[ZFS_MAXNAMELEN];
1798
1799 VERIFY0(dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds));
1800
1801 dsl_dataset_name(ds->ds_prev, namebuf);
1802 fnvlist_add_string(ddra->ddra_result, "target", namebuf);
1803
1804 cloneobj = dsl_dataset_create_sync(ds->ds_dir, "%rollback",
1805 ds->ds_prev, DS_CREATE_FLAG_NODIRTY, kcred, tx);
1806
1807 VERIFY0(dsl_dataset_hold_obj(dp, cloneobj, FTAG, &clone));
1808
1809 dsl_dataset_clone_swap_sync_impl(clone, ds, tx);
1810 dsl_dataset_zero_zil(ds, tx);
1811
1812 dsl_destroy_head_sync_impl(clone, tx);
1813
1814 dsl_dataset_rele(clone, FTAG);
1815 dsl_dataset_rele(ds, FTAG);
1816 }
1817
1818 /*
1819 * Rolls back the given filesystem or volume to the most recent snapshot.
1820 * The name of the most recent snapshot will be returned under key "target"
1821 * in the result nvlist.
1822 *
1823 * If owner != NULL:
1824 * - The existing dataset MUST be owned by the specified owner at entry
1825 * - Upon return, dataset will still be held by the same owner, whether we
1826 * succeed or not.
1827 *
1828 * This mode is required any time the existing filesystem is mounted. See
1829 * notes above zfs_suspend_fs() for further details.
1830 */
1831 int
1832 dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result)
1833 {
1834 dsl_dataset_rollback_arg_t ddra;
1835
1836 ddra.ddra_fsname = fsname;
1837 ddra.ddra_owner = owner;
1838 ddra.ddra_result = result;
1839
1840 return (dsl_sync_task(fsname, dsl_dataset_rollback_check,
1841 dsl_dataset_rollback_sync, &ddra, 1));
1842 }
1843
1844 struct promotenode {
1845 list_node_t link;
1846 dsl_dataset_t *ds;
1847 };
1848
1849 typedef struct dsl_dataset_promote_arg {
1850 const char *ddpa_clonename;
1851 dsl_dataset_t *ddpa_clone;
1852 list_t shared_snaps, origin_snaps, clone_snaps;
1853 dsl_dataset_t *origin_origin; /* origin of the origin */
1854 uint64_t used, comp, uncomp, unique, cloneusedsnap, originusedsnap;
1855 char *err_ds;
1856 } dsl_dataset_promote_arg_t;
1857
1858 static int snaplist_space(list_t *l, uint64_t mintxg, uint64_t *spacep);
1859 static int promote_hold(dsl_dataset_promote_arg_t *ddpa, dsl_pool_t *dp,
1860 void *tag);
1861 static void promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag);
|