Print this page
*** NO COMMENTS ***

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_ioctl.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_ioctl.c
↓ open down ↓ 3219 lines elided ↑ open up ↑
3220 3220   *
3221 3221   * outputs:     none
3222 3222   */
3223 3223  static int
3224 3224  zfs_ioc_rollback(zfs_cmd_t *zc)
3225 3225  {
3226 3226          dsl_dataset_t *ds, *clone;
3227 3227          int error;
3228 3228          zfsvfs_t *zfsvfs;
3229 3229          char *clone_name;
     3230 +        boolean_t umounted = B_FALSE;
     3231 +
     3232 +        if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
     3233 +                error = zfs_suspend_fs(zfsvfs);
     3234 +                if (error) {
     3235 +                        VFS_RELE(zfsvfs->z_vfs);
     3236 +                        return (error);
     3237 +                }
     3238 +
     3239 +                umounted = B_TRUE;
     3240 +        }
3230 3241  
3231 3242          error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
3232 3243          if (error)
3233      -                return (error);
     3244 +                goto out_vfs;
3234 3245  
3235 3246          /* must not be a snapshot */
3236 3247          if (dsl_dataset_is_snapshot(ds)) {
3237      -                dsl_dataset_rele(ds, FTAG);
3238      -                return (EINVAL);
     3248 +                error = EINVAL;
     3249 +                goto out_ds;
3239 3250          }
3240 3251  
3241 3252          /* must have a most recent snapshot */
3242 3253          if (ds->ds_phys->ds_prev_snap_txg < TXG_INITIAL) {
3243      -                dsl_dataset_rele(ds, FTAG);
3244      -                return (EINVAL);
     3254 +                error = EINVAL;
     3255 +                goto out_ds;
3245 3256          }
3246 3257  
3247 3258          /*
3248 3259           * Create clone of most recent snapshot.
3249 3260           */
3250 3261          clone_name = kmem_asprintf("%s/%%rollback", zc->zc_name);
3251 3262          error = dmu_objset_clone(clone_name, ds->ds_prev, DS_FLAG_INCONSISTENT);
3252 3263          if (error)
3253 3264                  goto out;
3254 3265  
3255 3266          error = dsl_dataset_own(clone_name, B_TRUE, FTAG, &clone);
3256 3267          if (error)
3257 3268                  goto out;
3258 3269  
3259 3270          /*
3260 3271           * Do clone swap.
3261 3272           */
3262      -        if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
3263      -                error = zfs_suspend_fs(zfsvfs);
3264      -                if (error == 0) {
3265      -                        int resume_err;
3266      -
3267      -                        if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
3268      -                                error = dsl_dataset_clone_swap(clone, ds,
3269      -                                    B_TRUE);
3270      -                                dsl_dataset_disown(ds, FTAG);
3271      -                                ds = NULL;
3272      -                        } else {
3273      -                                error = EBUSY;
3274      -                        }
3275      -                        resume_err = zfs_resume_fs(zfsvfs, zc->zc_name);
3276      -                        error = error ? error : resume_err;
     3273 +        if (umounted) {
     3274 +                if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
     3275 +                        error = dsl_dataset_clone_swap(clone, ds,
     3276 +                            B_TRUE);
     3277 +                        dsl_dataset_disown(ds, FTAG);
     3278 +                        ds = NULL;
     3279 +                } else {
     3280 +                        error = EBUSY;
3277 3281                  }
3278      -                VFS_RELE(zfsvfs->z_vfs);
3279 3282          } else {
3280 3283                  if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
3281 3284                          error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
3282 3285                          dsl_dataset_disown(ds, FTAG);
3283 3286                          ds = NULL;
3284 3287                  } else {
3285 3288                          error = EBUSY;
3286 3289                  }
3287 3290          }
3288 3291  
3289 3292          /*
3290 3293           * Destroy clone (which also closes it).
3291 3294           */
3292 3295          (void) dsl_dataset_destroy(clone, FTAG, B_FALSE);
3293 3296  
3294 3297  out:
3295 3298          strfree(clone_name);
     3299 +out_ds:
3296 3300          if (ds)
3297 3301                  dsl_dataset_rele(ds, FTAG);
     3302 +out_vfs:
     3303 +        if (umounted) {
     3304 +                int resume_err;
     3305 +
     3306 +                resume_err = zfs_resume_fs(zfsvfs, zc->zc_name);
     3307 +                error = error ? error : resume_err;
     3308 +                VFS_RELE(zfsvfs->z_vfs);
     3309 +        }
     3310 +
3298 3311          return (error);
3299 3312  }
3300 3313  
3301 3314  /*
3302 3315   * inputs:
3303 3316   * zc_name      old name of dataset
3304 3317   * zc_value     new name of dataset
3305 3318   * zc_cookie    recursive flag (only valid for snapshots)
3306 3319   *
3307 3320   * outputs:     none
↓ open down ↓ 386 lines elided ↑ open up ↑
3694 3707                  goto out;
3695 3708  
3696 3709          /*
3697 3710           * Set properties before we receive the stream so that they are applied
3698 3711           * to the new data. Note that we must call dmu_recv_stream() if
3699 3712           * dmu_recv_begin() succeeds.
3700 3713           */
3701 3714          if (props) {
3702 3715                  nvlist_t *errlist;
3703 3716  
3704      -                if (dmu_objset_from_ds(drc.drc_logical_ds, &os) == 0) {
     3717 +                if (drc.drc_newfs)
     3718 +                        error = dmu_objset_from_ds(drc.drc_real_ds, &os);
     3719 +                else
     3720 +                        error = dmu_objset_hold(tofs, FTAG, &os);
     3721 +
     3722 +                if (error == 0) {
3705 3723                          if (drc.drc_newfs) {
3706 3724                                  if (spa_version(os->os_spa) >=
3707 3725                                      SPA_VERSION_RECVD_PROPS)
3708 3726                                          first_recvd_props = B_TRUE;
3709 3727                          } else if (origprops != NULL) {
3710 3728                                  if (clear_received_props(os, tofs, origprops,
3711 3729                                      first_recvd_props ? NULL : props) != 0)
3712 3730                                          zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3713 3731                          } else {
3714 3732                                  zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3715 3733                          }
3716 3734                          dsl_prop_set_hasrecvd(os);
     3735 +
     3736 +                        if (!drc.drc_newfs)
     3737 +                                dmu_objset_rele(os, FTAG);
3717 3738                  } else if (!drc.drc_newfs) {
3718 3739                          zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3719 3740                  }
3720 3741  
3721 3742                  (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
3722 3743                      props, &errlist);
3723 3744                  (void) nvlist_merge(errors, errlist, 0);
3724 3745                  nvlist_free(errlist);
3725 3746          }
3726 3747  
↓ open down ↓ 1608 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX