3535 * zc_name old name of dataset
3536 * zc_value new name of dataset
3537 * zc_cookie recursive flag (only valid for snapshots)
3538 *
3539 * outputs: none
3540 */
3541 static int
3542 zfs_ioc_rename(zfs_cmd_t *zc)
3543 {
3544 boolean_t recursive = zc->zc_cookie & 1;
3545 char *at;
3546
3547 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
3548 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
3549 strchr(zc->zc_value, '%'))
3550 return (SET_ERROR(EINVAL));
3551
3552 at = strchr(zc->zc_name, '@');
3553 if (at != NULL) {
3554 /* snaps must be in same fs */
3555 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
3556 return (SET_ERROR(EXDEV));
3557 *at = '\0';
3558 if (zc->zc_objset_type == DMU_OST_ZFS) {
3559 int error = dmu_objset_find(zc->zc_name,
3560 recursive_unmount, at + 1,
3561 recursive ? DS_FIND_CHILDREN : 0);
3562 if (error != 0)
3563 return (error);
3564 }
3565 return (dsl_dataset_rename_snapshot(zc->zc_name,
3566 at + 1, strchr(zc->zc_value, '@') + 1, recursive));
3567 } else {
3568 if (zc->zc_objset_type == DMU_OST_ZVOL)
3569 (void) zvol_remove_minor(zc->zc_name);
3570 return (dsl_dir_rename(zc->zc_name, zc->zc_value));
3571 }
3572 }
3573
3574 static int
3575 zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
3576 {
3577 const char *propname = nvpair_name(pair);
3578 boolean_t issnap = (strchr(dsname, '@') != NULL);
3579 zfs_prop_t prop = zfs_name_to_prop(propname);
3580 uint64_t intval;
3581 int err;
3582
3583 if (prop == ZPROP_INVAL) {
3584 if (zfs_prop_user(propname)) {
3585 if (err = zfs_secpolicy_write_perms(dsname,
3586 ZFS_DELEG_PERM_USERPROP, cr))
|
3535 * zc_name old name of dataset
3536 * zc_value new name of dataset
3537 * zc_cookie recursive flag (only valid for snapshots)
3538 *
3539 * outputs: none
3540 */
3541 static int
3542 zfs_ioc_rename(zfs_cmd_t *zc)
3543 {
3544 boolean_t recursive = zc->zc_cookie & 1;
3545 char *at;
3546
3547 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
3548 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
3549 strchr(zc->zc_value, '%'))
3550 return (SET_ERROR(EINVAL));
3551
3552 at = strchr(zc->zc_name, '@');
3553 if (at != NULL) {
3554 /* snaps must be in same fs */
3555 int error;
3556
3557 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
3558 return (SET_ERROR(EXDEV));
3559 *at = '\0';
3560 if (zc->zc_objset_type == DMU_OST_ZFS) {
3561 error = dmu_objset_find(zc->zc_name,
3562 recursive_unmount, at + 1,
3563 recursive ? DS_FIND_CHILDREN : 0);
3564 if (error != 0) {
3565 *at = '@';
3566 return (error);
3567 }
3568 }
3569 error = dsl_dataset_rename_snapshot(zc->zc_name,
3570 at + 1, strchr(zc->zc_value, '@') + 1, recursive);
3571 *at = '@';
3572
3573 return (error);
3574 } else {
3575 if (zc->zc_objset_type == DMU_OST_ZVOL)
3576 (void) zvol_remove_minor(zc->zc_name);
3577 return (dsl_dir_rename(zc->zc_name, zc->zc_value));
3578 }
3579 }
3580
3581 static int
3582 zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
3583 {
3584 const char *propname = nvpair_name(pair);
3585 boolean_t issnap = (strchr(dsname, '@') != NULL);
3586 zfs_prop_t prop = zfs_name_to_prop(propname);
3587 uint64_t intval;
3588 int err;
3589
3590 if (prop == ZPROP_INVAL) {
3591 if (zfs_prop_user(propname)) {
3592 if (err = zfs_secpolicy_write_perms(dsname,
3593 ZFS_DELEG_PERM_USERPROP, cr))
|