Print this page
*** NO COMMENTS ***

*** 3225,3249 **** { dsl_dataset_t *ds, *clone; int error; zfsvfs_t *zfsvfs; char *clone_name; error = dsl_dataset_hold(zc->zc_name, FTAG, &ds); if (error) ! return (error); /* must not be a snapshot */ if (dsl_dataset_is_snapshot(ds)) { ! dsl_dataset_rele(ds, FTAG); ! return (EINVAL); } /* must have a most recent snapshot */ if (ds->ds_phys->ds_prev_snap_txg < TXG_INITIAL) { ! dsl_dataset_rele(ds, FTAG); ! return (EINVAL); } /* * Create clone of most recent snapshot. */ --- 3225,3260 ---- { dsl_dataset_t *ds, *clone; int error; zfsvfs_t *zfsvfs; char *clone_name; + boolean_t umounted = B_FALSE; + + if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { + error = zfs_suspend_fs(zfsvfs); + if (error) { + VFS_RELE(zfsvfs->z_vfs); + return (error); + } + + umounted = B_TRUE; + } error = dsl_dataset_hold(zc->zc_name, FTAG, &ds); if (error) ! goto out_vfs; /* must not be a snapshot */ if (dsl_dataset_is_snapshot(ds)) { ! error = EINVAL; ! goto out_ds; } /* must have a most recent snapshot */ if (ds->ds_phys->ds_prev_snap_txg < TXG_INITIAL) { ! error = EINVAL; ! goto out_ds; } /* * Create clone of most recent snapshot. */
*** 3257,3283 **** goto out; /* * Do clone swap. */ ! if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { ! error = zfs_suspend_fs(zfsvfs); ! if (error == 0) { ! int resume_err; ! if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { error = dsl_dataset_clone_swap(clone, ds, B_TRUE); dsl_dataset_disown(ds, FTAG); ds = NULL; } else { error = EBUSY; } - resume_err = zfs_resume_fs(zfsvfs, zc->zc_name); - error = error ? error : resume_err; - } - VFS_RELE(zfsvfs->z_vfs); } else { if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { error = dsl_dataset_clone_swap(clone, ds, B_TRUE); dsl_dataset_disown(ds, FTAG); ds = NULL; --- 3268,3286 ---- goto out; /* * Do clone swap. */ ! if (umounted) { if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { error = dsl_dataset_clone_swap(clone, ds, B_TRUE); dsl_dataset_disown(ds, FTAG); ds = NULL; } else { error = EBUSY; } } else { if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { error = dsl_dataset_clone_swap(clone, ds, B_TRUE); dsl_dataset_disown(ds, FTAG); ds = NULL;
*** 3291,3302 **** --- 3294,3315 ---- */ (void) dsl_dataset_destroy(clone, FTAG, B_FALSE); out: strfree(clone_name); + out_ds: if (ds) dsl_dataset_rele(ds, FTAG); + out_vfs: + if (umounted) { + int resume_err; + + resume_err = zfs_resume_fs(zfsvfs, zc->zc_name); + error = error ? error : resume_err; + VFS_RELE(zfsvfs->z_vfs); + } + return (error); } /* * inputs:
*** 3699,3709 **** * dmu_recv_begin() succeeds. */ if (props) { nvlist_t *errlist; ! if (dmu_objset_from_ds(drc.drc_logical_ds, &os) == 0) { if (drc.drc_newfs) { if (spa_version(os->os_spa) >= SPA_VERSION_RECVD_PROPS) first_recvd_props = B_TRUE; } else if (origprops != NULL) { --- 3712,3727 ---- * dmu_recv_begin() succeeds. */ if (props) { nvlist_t *errlist; ! if (drc.drc_newfs) ! error = dmu_objset_from_ds(drc.drc_real_ds, &os); ! else ! error = dmu_objset_hold(tofs, FTAG, &os); ! ! if (error == 0) { if (drc.drc_newfs) { if (spa_version(os->os_spa) >= SPA_VERSION_RECVD_PROPS) first_recvd_props = B_TRUE; } else if (origprops != NULL) {
*** 3712,3721 **** --- 3730,3742 ---- zc->zc_obj |= ZPROP_ERR_NOCLEAR; } else { zc->zc_obj |= ZPROP_ERR_NOCLEAR; } dsl_prop_set_hasrecvd(os); + + if (!drc.drc_newfs) + dmu_objset_rele(os, FTAG); } else if (!drc.drc_newfs) { zc->zc_obj |= ZPROP_ERR_NOCLEAR; } (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,