mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-26 20:22:14 +03:00
Illumos 4368, 4369.
4369 implement zfs bookmarks 4368 zfs send filesystems from readonly pools Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org> References: https://www.illumos.org/issues/4369 https://www.illumos.org/issues/4368 https://github.com/illumos/illumos-gate/commit/78f1710 Ported by: Tim Chase <tim@chase2k.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2530
This commit is contained in:
committed by
Brian Behlendorf
parent
b0bc7a84d9
commit
da536844d5
@@ -48,6 +48,7 @@
|
||||
#include <sys/dsl_deadlist.h>
|
||||
#include <sys/dsl_destroy.h>
|
||||
#include <sys/dsl_userhold.h>
|
||||
#include <sys/dsl_bookmark.h>
|
||||
|
||||
#define SWITCH64(x, y) \
|
||||
{ \
|
||||
@@ -404,6 +405,14 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
||||
ds->ds_phys->ds_prev_snap_obj,
|
||||
ds, &ds->ds_prev);
|
||||
}
|
||||
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
|
||||
int zaperr = zap_lookup(mos, ds->ds_object,
|
||||
DS_FIELD_BOOKMARK_NAMES,
|
||||
sizeof (ds->ds_bookmarks), 1,
|
||||
&ds->ds_bookmarks);
|
||||
if (zaperr != ENOENT)
|
||||
VERIFY0(zaperr);
|
||||
}
|
||||
} else {
|
||||
if (zfs_flags & ZFS_DEBUG_SNAPNAMES)
|
||||
err = dsl_dataset_get_snapname(ds);
|
||||
@@ -1734,6 +1743,8 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
|
||||
dsl_dataset_t *ds;
|
||||
int64_t unused_refres_delta;
|
||||
int error;
|
||||
nvpair_t *pair;
|
||||
nvlist_t *proprequest, *bookmarks;
|
||||
|
||||
error = dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds);
|
||||
if (error != 0)
|
||||
@@ -1751,6 +1762,28 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
/* must not have any bookmarks after the most recent snapshot */
|
||||
proprequest = fnvlist_alloc();
|
||||
fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG));
|
||||
bookmarks = fnvlist_alloc();
|
||||
error = dsl_get_bookmarks_impl(ds, proprequest, bookmarks);
|
||||
fnvlist_free(proprequest);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
for (pair = nvlist_next_nvpair(bookmarks, NULL);
|
||||
pair != NULL; pair = nvlist_next_nvpair(bookmarks, pair)) {
|
||||
nvlist_t *valuenv =
|
||||
fnvlist_lookup_nvlist(fnvpair_value_nvlist(pair),
|
||||
zfs_prop_to_name(ZFS_PROP_CREATETXG));
|
||||
uint64_t createtxg = fnvlist_lookup_uint64(valuenv, "value");
|
||||
if (createtxg > ds->ds_phys->ds_prev_snap_txg) {
|
||||
fnvlist_free(bookmarks);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
}
|
||||
fnvlist_free(bookmarks);
|
||||
|
||||
error = dsl_dataset_handoff_check(ds, ddra->ddra_owner, tx);
|
||||
if (error != 0) {
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
@@ -2972,9 +3005,12 @@ dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap,
|
||||
* 'earlier' is before 'later'. Or 'earlier' could be the origin of
|
||||
* 'later's filesystem. Or 'earlier' could be an older snapshot in the origin's
|
||||
* filesystem. Or 'earlier' could be the origin's origin.
|
||||
*
|
||||
* If non-zero, earlier_txg is used instead of earlier's ds_creation_txg.
|
||||
*/
|
||||
boolean_t
|
||||
dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier)
|
||||
dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier,
|
||||
uint64_t earlier_txg)
|
||||
{
|
||||
dsl_pool_t *dp = later->ds_dir->dd_pool;
|
||||
int error;
|
||||
@@ -2982,9 +3018,13 @@ dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier)
|
||||
dsl_dataset_t *origin;
|
||||
|
||||
ASSERT(dsl_pool_config_held(dp));
|
||||
ASSERT(dsl_dataset_is_snapshot(earlier) || earlier_txg != 0);
|
||||
|
||||
if (earlier->ds_phys->ds_creation_txg >=
|
||||
later->ds_phys->ds_creation_txg)
|
||||
if (earlier_txg == 0)
|
||||
earlier_txg = earlier->ds_phys->ds_creation_txg;
|
||||
|
||||
if (dsl_dataset_is_snapshot(later) &&
|
||||
earlier_txg >= later->ds_phys->ds_creation_txg)
|
||||
return (B_FALSE);
|
||||
|
||||
if (later->ds_dir == earlier->ds_dir)
|
||||
@@ -2998,7 +3038,7 @@ dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier)
|
||||
later->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin);
|
||||
if (error != 0)
|
||||
return (B_FALSE);
|
||||
ret = dsl_dataset_is_before(origin, earlier);
|
||||
ret = dsl_dataset_is_before(origin, earlier, earlier_txg);
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user