Print this page
*** NO COMMENTS ***


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2012 by Delphix. All rights reserved.
  28  */
  29 
  30 /*
  31  * ZFS ioctls.
  32  *
  33  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  34  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  35  *
  36  * There are two ways that we handle ioctls: the legacy way where almost
  37  * all of the logic is in the ioctl callback, and the new way where most
  38  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  39  *
  40  * Non-legacy ioctls should be registered by calling
  41  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  42  * from userland by lzc_ioctl().
  43  *
  44  * The registration arguments are as follows:
  45  *


3155                 cbfunc = zfs_create_cb;
3156                 break;
3157 
3158         case DMU_OST_ZVOL:
3159                 cbfunc = zvol_create_cb;
3160                 break;
3161 
3162         default:
3163                 cbfunc = NULL;
3164                 break;
3165         }
3166         if (strchr(fsname, '@') ||
3167             strchr(fsname, '%'))
3168                 return (EINVAL);
3169 
3170         zct.zct_props = nvprops;
3171 
3172         if (cbfunc == NULL)
3173                 return (EINVAL);
3174 
3175         if (zfs_get_parent(name, parent, MAXNAMELEN) == 0 &&
3176             zfs_is_wormed(parent)) {
3177                 return (EPERM);
3178         }
3179 
3180         if (type == DMU_OST_ZVOL) {
3181                 uint64_t volsize, volblocksize;
3182 
3183                 if (nvprops == NULL)
3184                         return (EINVAL);
3185                 if (nvlist_lookup_uint64(nvprops,
3186                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
3187                         return (EINVAL);
3188 
3189                 if ((error = nvlist_lookup_uint64(nvprops,
3190                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3191                     &volblocksize)) != 0 && error != ENOENT)
3192                         return (EINVAL);
3193 
3194                 if (error != 0)
3195                         volblocksize = zfs_prop_default_numeric(


4171                         error = dsl_dataset_hold_obj(dp,
4172                             ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &dsfrom);
4173                         rw_exit(&dp->dp_config_rwlock);
4174                         if (error) {
4175                                 dsl_dataset_rele(ds, FTAG);
4176                                 return (error);
4177                         }
4178                         error = dmu_objset_from_ds(dsfrom, &fromsnap);
4179                         if (error) {
4180                                 dsl_dataset_rele(dsfrom, FTAG);
4181                                 dsl_dataset_rele(ds, FTAG);
4182                                 return (error);
4183                         }
4184                 }
4185         }
4186 
4187         if (estimate) {
4188                 error = dmu_send_estimate(tosnap, fromsnap,
4189                     &zc->zc_objset_type);
4190         } else {

4191                 file_t *fp = getf(zc->zc_cookie);
4192                 if (fp == NULL) {
4193                         dsl_dataset_rele(ds, FTAG);
4194                         if (dsfrom)
4195                                 dsl_dataset_rele(dsfrom, FTAG);
4196                         return (EBADF);
4197                 }
4198 
4199                 off = fp->f_offset;
4200                 error = dmu_send(tosnap, fromsnap,
4201                     zc->zc_cookie, fp->f_vnode, &off);

4202 

4203                 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4204                         fp->f_offset = off;
4205                 releasef(zc->zc_cookie);
4206         }
4207         if (dsfrom)
4208                 dsl_dataset_rele(dsfrom, FTAG);
4209         dsl_dataset_rele(ds, FTAG);
4210         return (error);
4211 }
4212 
4213 /*
4214  * inputs:
4215  * zc_name      name of snapshot on which to report progress
4216  * zc_cookie    file descriptor of send stream
4217  *
4218  * outputs:
4219  * zc_cookie    number of bytes written in send stream thus far
4220  */
4221 static int
4222 zfs_ioc_send_progress(zfs_cmd_t *zc)


5155                 return (error);
5156 
5157         error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5158         if (error == 0) {
5159                 error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5160                 if (error) {
5161                         dmu_objset_rele(tosnap, FTAG);
5162                         return (error);
5163                 }
5164         }
5165 
5166         file_t *fp = getf(fd);
5167         if (fp == NULL) {
5168                 dmu_objset_rele(tosnap, FTAG);
5169                 if (fromsnap != NULL)
5170                         dmu_objset_rele(fromsnap, FTAG);
5171                 return (EBADF);
5172         }
5173 
5174         off = fp->f_offset;
5175         error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5176 
5177         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5178                 fp->f_offset = off;
5179         releasef(fd);
5180         if (fromsnap != NULL)
5181                 dmu_objset_rele(fromsnap, FTAG);
5182         dmu_objset_rele(tosnap, FTAG);
5183         return (error);
5184 }
5185 
5186 /*
5187  * Determine approximately how large a zfs send stream will be -- the number
5188  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5189  *
5190  * innvl: {
5191  *     (optional) "fromsnap" -> full snap name to send an incremental from
5192  * }
5193  *
5194  * outnvl: {
5195  *     "space" -> bytes of space (uint64)




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2012 by Delphix. All rights reserved.
  28  */
  29 
  30 /*
  31  * ZFS ioctls.
  32  *
  33  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  34  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  35  *
  36  * There are two ways that we handle ioctls: the legacy way where almost
  37  * all of the logic is in the ioctl callback, and the new way where most
  38  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  39  *
  40  * Non-legacy ioctls should be registered by calling
  41  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  42  * from userland by lzc_ioctl().
  43  *
  44  * The registration arguments are as follows:
  45  *


3155                 cbfunc = zfs_create_cb;
3156                 break;
3157 
3158         case DMU_OST_ZVOL:
3159                 cbfunc = zvol_create_cb;
3160                 break;
3161 
3162         default:
3163                 cbfunc = NULL;
3164                 break;
3165         }
3166         if (strchr(fsname, '@') ||
3167             strchr(fsname, '%'))
3168                 return (EINVAL);
3169 
3170         zct.zct_props = nvprops;
3171 
3172         if (cbfunc == NULL)
3173                 return (EINVAL);
3174 
3175         if (zfs_get_parent(fsname, parent, MAXNAMELEN) == 0 &&
3176             zfs_is_wormed(parent)) {
3177                 return (EPERM);
3178         }
3179 
3180         if (type == DMU_OST_ZVOL) {
3181                 uint64_t volsize, volblocksize;
3182 
3183                 if (nvprops == NULL)
3184                         return (EINVAL);
3185                 if (nvlist_lookup_uint64(nvprops,
3186                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
3187                         return (EINVAL);
3188 
3189                 if ((error = nvlist_lookup_uint64(nvprops,
3190                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3191                     &volblocksize)) != 0 && error != ENOENT)
3192                         return (EINVAL);
3193 
3194                 if (error != 0)
3195                         volblocksize = zfs_prop_default_numeric(


4171                         error = dsl_dataset_hold_obj(dp,
4172                             ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &dsfrom);
4173                         rw_exit(&dp->dp_config_rwlock);
4174                         if (error) {
4175                                 dsl_dataset_rele(ds, FTAG);
4176                                 return (error);
4177                         }
4178                         error = dmu_objset_from_ds(dsfrom, &fromsnap);
4179                         if (error) {
4180                                 dsl_dataset_rele(dsfrom, FTAG);
4181                                 dsl_dataset_rele(ds, FTAG);
4182                                 return (error);
4183                         }
4184                 }
4185         }
4186 
4187         if (estimate) {
4188                 error = dmu_send_estimate(tosnap, fromsnap,
4189                     &zc->zc_objset_type);
4190         } else {
4191                 offset_t off_starting;
4192                 file_t *fp = getf(zc->zc_cookie);
4193                 if (fp == NULL) {
4194                         dsl_dataset_rele(ds, FTAG);
4195                         if (dsfrom)
4196                                 dsl_dataset_rele(dsfrom, FTAG);
4197                         return (EBADF);
4198                 }
4199 
4200                 off = fp->f_offset;
4201                 off_starting = off;
4202                 error = dmu_send(tosnap, fromsnap, zc->zc_cookie, fp->f_vnode,
4203                     &off, zc->zc_sendsize);
4204 
4205                 zc->zc_sendcounter = off - off_starting;
4206                 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4207                         fp->f_offset = off;
4208                 releasef(zc->zc_cookie);
4209         }
4210         if (dsfrom)
4211                 dsl_dataset_rele(dsfrom, FTAG);
4212         dsl_dataset_rele(ds, FTAG);
4213         return (error);
4214 }
4215 
4216 /*
4217  * inputs:
4218  * zc_name      name of snapshot on which to report progress
4219  * zc_cookie    file descriptor of send stream
4220  *
4221  * outputs:
4222  * zc_cookie    number of bytes written in send stream thus far
4223  */
4224 static int
4225 zfs_ioc_send_progress(zfs_cmd_t *zc)


5158                 return (error);
5159 
5160         error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5161         if (error == 0) {
5162                 error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5163                 if (error) {
5164                         dmu_objset_rele(tosnap, FTAG);
5165                         return (error);
5166                 }
5167         }
5168 
5169         file_t *fp = getf(fd);
5170         if (fp == NULL) {
5171                 dmu_objset_rele(tosnap, FTAG);
5172                 if (fromsnap != NULL)
5173                         dmu_objset_rele(fromsnap, FTAG);
5174                 return (EBADF);
5175         }
5176 
5177         off = fp->f_offset;
5178         error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off, B_FALSE);
5179 
5180         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5181                 fp->f_offset = off;
5182         releasef(fd);
5183         if (fromsnap != NULL)
5184                 dmu_objset_rele(fromsnap, FTAG);
5185         dmu_objset_rele(tosnap, FTAG);
5186         return (error);
5187 }
5188 
5189 /*
5190  * Determine approximately how large a zfs send stream will be -- the number
5191  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5192  *
5193  * innvl: {
5194  *     (optional) "fromsnap" -> full snap name to send an incremental from
5195  * }
5196  *
5197  * outnvl: {
5198  *     "space" -> bytes of space (uint64)