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,