403
438
make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
406
libzfs_handle_t *hdl = zhp->zfs_hdl;
409
* Preserve history log string.
410
* any changes performed here will be
411
* logged as an internal event.
413
logstr = zhp->zfs_hdl->libzfs_log_str;
414
zhp->zfs_hdl->libzfs_log_str = NULL;
417
if (put_stats_zhdl(zhp, zc) != 0) {
418
zhp->zfs_hdl->libzfs_log_str = logstr;
440
if (put_stats_zhdl(zhp, zc) != 0)
423
if (zhp->zfs_dmustats.dds_inconsistent) {
424
zfs_cmd_t zc2 = { 0 };
427
* If it is dds_inconsistent, then we've caught it in
428
* the middle of a 'zfs receive' or 'zfs destroy', and
429
* it is inconsistent from the ZPL's point of view, so
430
* can't be mounted. However, it could also be that we
431
* have crashed in the middle of one of those
432
* operations, in which case we need to get rid of the
433
* inconsistent state. We do that by either rolling
434
* back to the previous snapshot (which will fail if
435
* there is none), or destroying the filesystem. Note
436
* that if we are still in the middle of an active
437
* 'receive' or 'destroy', then the rollback and destroy
438
* will fail with EBUSY and we will drive on as usual.
441
(void) strlcpy(zc2.zc_name, zhp->zfs_name,
442
sizeof (zc2.zc_name));
444
if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
445
(void) zvol_remove_link(hdl, zhp->zfs_name);
446
zc2.zc_objset_type = DMU_OST_ZVOL;
448
zc2.zc_objset_type = DMU_OST_ZFS;
452
* If we can successfully destroy it, pretend that it
455
if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc2) == 0) {
456
zhp->zfs_hdl->libzfs_log_str = logstr;
460
/* If we can successfully roll it back, reset the stats */
461
if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc2) == 0) {
462
if (get_stats_ioctl(zhp, zc) != 0) {
463
zhp->zfs_hdl->libzfs_log_str = logstr;
471
444
* We've managed to open the dataset and gather statistics. Determine
964
case ZFS_PROP_SHAREISCSI:
965
if (strcmp(strval, "off") != 0 &&
966
strcmp(strval, "on") != 0 &&
967
strcmp(strval, "type=disk") != 0) {
968
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
969
"'%s' must be 'on', 'off', or 'type=disk'"),
971
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
956
case ZFS_PROP_MLSLABEL:
959
* Verify the mlslabel string and convert to
960
* internal hex label string.
964
/* zfs-fuse : we are going to ignore all this for now
965
* 1 : they are supposed to be enforced by the kernel
966
* 2 : they use m_label_* api which is external
967
* so just forget it for now */
969
char *hex = NULL; /* internal label string */
971
/* Default value is already OK. */
972
if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
975
/* Verify the label can be converted to binary form */
976
if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
977
(str_to_label(strval, &new_sl, MAC_LABEL,
978
L_NO_CORRECTION, NULL) == -1)) {
982
/* Now translate to hex internal label string */
983
if (label_to_str(new_sl, &hex, M_INTERNAL,
989
m_label_free(new_sl);
991
/* If string is already in internal form, we're done. */
992
if (strcmp(strval, hex) == 0) {
997
/* Replace the label string with the internal form. */
998
nvlist_remove(ret, zfs_prop_to_name(prop),
1000
verify(nvlist_add_string(ret, zfs_prop_to_name(prop),
1008
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1009
"invalid mlslabel '%s'"), strval);
1010
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1011
// m_label_free(new_sl); /* OK if null */
977
1016
case ZFS_PROP_MOUNTPOINT:
979
1018
namecheck_err_t why;
1275
zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
1282
* For quotas and reservations, ENOSPC indicates
1283
* something different; setting a quota or reservation
1284
* doesn't use any disk space.
1287
case ZFS_PROP_QUOTA:
1288
case ZFS_PROP_REFQUOTA:
1289
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1290
"size is less than current used or "
1292
(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1295
case ZFS_PROP_RESERVATION:
1296
case ZFS_PROP_REFRESERVATION:
1297
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1298
"size is greater than available space"));
1299
(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1303
(void) zfs_standard_error(hdl, err, errbuf);
1309
(void) zfs_standard_error(hdl, EBUSY, errbuf);
1313
(void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1317
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1318
"pool and or dataset must be upgraded to set this "
1319
"property or value"));
1320
(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1324
if (prop == ZFS_PROP_COMPRESSION) {
1325
(void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1326
"property setting is not allowed on "
1327
"bootable datasets"));
1328
(void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1330
(void) zfs_standard_error(hdl, err, errbuf);
1335
if (prop == ZPROP_INVAL) {
1336
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1338
(void) zfs_standard_error(hdl, err, errbuf);
1344
* This platform can't address a volume this big.
1347
if (prop == ZFS_PROP_VOLSIZE) {
1348
(void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1354
(void) zfs_standard_error(hdl, err, errbuf);
1233
1359
* Given a property name and value, set the property for the given dataset.
1297
1423
ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1299
1425
if (ret != 0) {
1304
* For quotas and reservations, ENOSPC indicates
1305
* something different; setting a quota or reservation
1306
* doesn't use any disk space.
1309
case ZFS_PROP_QUOTA:
1310
case ZFS_PROP_REFQUOTA:
1311
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1312
"size is less than current used or "
1314
(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1317
case ZFS_PROP_RESERVATION:
1318
case ZFS_PROP_REFRESERVATION:
1319
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1320
"size is greater than available space"));
1321
(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1325
(void) zfs_standard_error(hdl, errno, errbuf);
1331
if (prop == ZFS_PROP_VOLBLOCKSIZE)
1332
(void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
1334
(void) zfs_standard_error(hdl, EBUSY, errbuf);
1338
(void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1342
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1343
"pool and or dataset must be upgraded to set this "
1344
"property or value"));
1345
(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1349
if (prop == ZFS_PROP_COMPRESSION) {
1350
(void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1351
"property setting is not allowed on "
1352
"bootable datasets"));
1353
(void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1355
(void) zfs_standard_error(hdl, errno, errbuf);
1361
* This platform can't address a volume this big.
1364
if (prop == ZFS_PROP_VOLSIZE) {
1365
(void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1371
(void) zfs_standard_error(hdl, errno, errbuf);
1426
zfs_setprop_error(hdl, prop, errno, errbuf);
1375
1429
ret = changelist_postfix(cl);
2983
3142
return (zfs_standard_error(zhp->zfs_hdl, errno,
2986
} else if (ZFS_IS_VOLUME(zhp)) {
2987
ret = zvol_create_link(zhp->zfs_hdl, target);
2993
typedef struct promote_data {
2994
char cb_mountpoint[MAXPATHLEN];
2995
const char *cb_target;
2996
const char *cb_errbuf;
2997
uint64_t cb_pivot_txg;
3001
promote_snap_cb(zfs_handle_t *zhp, void *data)
3003
promote_data_t *pd = data;
3005
char snapname[MAXPATHLEN];
3008
/* We don't care about snapshots after the pivot point */
3009
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg) {
3014
/* Remove the device link if it's a zvol. */
3015
if (ZFS_IS_VOLUME(zhp))
3016
(void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
3018
/* Check for conflicting names */
3019
(void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
3020
(void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
3021
szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
3024
zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3025
"snapshot name '%s' from origin \n"
3026
"conflicts with '%s' from target"),
3027
zhp->zfs_name, snapname);
3028
rv = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf);
3035
promote_snap_done_cb(zfs_handle_t *zhp, void *data)
3037
promote_data_t *pd = data;
3039
/* We don't care about snapshots after the pivot point */
3040
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) <= pd->cb_pivot_txg) {
3041
/* Create the device link if it's a zvol. */
3042
if (ZFS_IS_VOLUME(zhp))
3043
(void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
3051
3151
* Promotes the given clone fs to be the clone parent.
3108
3183
if (ret != 0) {
3109
3184
int save_errno = errno;
3111
(void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
3114
3186
switch (save_errno) {
3117
* There is a conflicting snapshot name. We
3118
* should have caught this above, but they could
3119
* have renamed something in the mean time.
3188
/* There is a conflicting snapshot name. */
3121
3189
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3122
"conflicting snapshot name from parent '%s'"),
3190
"conflicting snapshot '%s' from parent '%s'"),
3191
zc.zc_string, parent);
3124
3192
return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3127
3195
return (zfs_standard_error(hdl, save_errno, errbuf));
3130
(void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
3138
const char *cd_snapname;
3143
zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
3145
struct createdata *cd = arg;
3148
if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3149
char name[MAXPATHLEN];
3151
(void) strlcpy(name, zhp->zfs_name, sizeof (name));
3152
(void) strlcat(name, "@", sizeof (name));
3153
(void) strlcat(name, cd->cd_snapname, sizeof (name));
3154
(void) zvol_create_link_common(zhp->zfs_hdl, name,
3157
* NB: this is simply a best-effort. We don't want to
3158
* return an error, because then we wouldn't visit all
3163
ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, cd);
3663
* Given a zvol dataset, issue the ioctl to create the appropriate minor node,
3664
* poke devfsadm to create the /dev link, and then wait for the link to appear.
3667
zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
3669
return (zvol_create_link_common(hdl, dataset, B_FALSE));
3673
zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
3676
zfs_cmd_t zc = { 0 };
3677
di_devlink_handle_t dhdl;
3678
priv_set_t *priv_effective;
3681
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3684
* Issue the appropriate ioctl.
3686
if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
3690
* Silently ignore the case where the link already
3691
* exists. This allows 'zfs volinit' to be run multiple
3692
* times without errors.
3698
* Dataset does not exist in the kernel. If we
3699
* don't care (see zfs_rename), then ignore the
3709
return (zfs_standard_error_fmt(hdl, errno,
3710
dgettext(TEXT_DOMAIN, "cannot create device links "
3711
"for '%s'"), dataset));
3716
* If privileged call devfsadm and wait for the links to
3718
* Otherwise, print out an informational message.
3721
priv_effective = priv_allocset();
3722
(void) getppriv(PRIV_EFFECTIVE, priv_effective);
3723
privileged = (priv_isfullset(priv_effective) == B_TRUE);
3724
priv_freeset(priv_effective);
3727
if ((dhdl = di_devlink_init(ZFS_DRIVER,
3728
DI_MAKE_LINK)) == NULL) {
3729
zfs_error_aux(hdl, strerror(errno));
3730
(void) zfs_error_fmt(hdl, errno,
3731
dgettext(TEXT_DOMAIN, "cannot create device links "
3732
"for '%s'"), dataset);
3733
(void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
3736
(void) di_devlink_fini(&dhdl);
3739
char pathname[MAXPATHLEN];
3740
struct stat64 statbuf;
3746
* This is the poor mans way of waiting for the link
3747
* to show up. If after 10 seconds we still don't
3748
* have it, then print out a message.
3750
(void) snprintf(pathname, sizeof (pathname), "/dev/zvol/dsk/%s",
3753
for (i = 0; i != MAX_WAIT; i++) {
3754
if (stat64(pathname, &statbuf) == 0)
3759
(void) printf(gettext("%s may not be immediately "
3760
"available\n"), pathname);
3766
/* zfs-fuse TODO: implement ZVOLs */
3771
* Remove a minor node for the given zvol and the associated /dev links.
3774
zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
3776
zfs_cmd_t zc = { 0 };
3778
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3780
if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
3784
* Silently ignore the case where the link no longer
3785
* exists, so that 'zfs volfini' can be run multiple
3786
* times without errors.
3791
return (zfs_standard_error_fmt(hdl, errno,
3792
dgettext(TEXT_DOMAIN, "cannot remove device "
3793
"links for '%s'"), dataset));
3801
3637
zfs_get_user_props(zfs_handle_t *zhp)
3803
3639
return (zhp->zfs_user_props);
3643
zfs_get_recvd_props(zfs_handle_t *zhp)
3645
if (zhp->zfs_recvd_props == NULL)
3646
if (get_recvd_props_ioctl(zhp) != 0)
3648
return (zhp->zfs_recvd_props);
3807
3652
* This function is used by 'zfs list' to determine the exact set of columns to
3808
3653
* display, and their maximum widths. This does two main things:
3886
3733
if (strlen(buf) > entry->pl_width)
3887
3734
entry->pl_width = strlen(buf);
3889
} else if (nvlist_lookup_nvlist(userprops,
3890
entry->pl_user_prop, &propval) == 0) {
3891
verify(nvlist_lookup_string(propval,
3892
ZPROP_VALUE, &strval) == 0);
3893
if (strlen(strval) > entry->pl_width)
3894
entry->pl_width = strlen(strval);
3736
if (received && zfs_prop_get_recvd(zhp,
3737
zfs_prop_to_name(entry->pl_prop),
3738
buf, sizeof (buf), B_FALSE) == 0)
3739
if (strlen(buf) > entry->pl_recvd_width)
3740
entry->pl_recvd_width = strlen(buf);
3742
if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
3744
verify(nvlist_lookup_string(propval,
3745
ZPROP_VALUE, &strval) == 0);
3746
if (strlen(strval) > entry->pl_width)
3747
entry->pl_width = strlen(strval);
3749
if (received && zfs_prop_get_recvd(zhp,
3750
entry->pl_user_prop,
3751
buf, sizeof (buf), B_FALSE) == 0)
3752
if (strlen(buf) > entry->pl_recvd_width)
3753
entry->pl_recvd_width = strlen(buf);
3902
zfs_iscsi_perm_check(libzfs_handle_t *hdl, char *dataset, ucred_t *cred)
3904
/* ZFS-FUSE: not implemented */
3907
zfs_cmd_t zc = { 0 };
3911
const gid_t *groups;
3915
if (nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0) != 0)
3916
return (no_memory(hdl));
3918
uid = ucred_geteuid(cred);
3919
gid = ucred_getegid(cred);
3920
group_cnt = ucred_getgroups(cred, &groups);
3922
if (uid == (uid_t)-1 || gid == (uid_t)-1 || group_cnt == (uid_t)-1)
3925
if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_UID, uid) != 0) {
3930
if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_GID, gid) != 0) {
3935
if (nvlist_add_uint32_array(nvp,
3936
ZFS_DELEG_PERM_GROUPS, (uint32_t *)groups, group_cnt) != 0) {
3940
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3942
if (zcmd_write_src_nvlist(hdl, &zc, nvp))
3945
error = ioctl(hdl->libzfs_fd, ZFS_IOC_ISCSI_PERM_CHECK, &zc);
3952
3761
zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
3953
3762
char *resource, void *export, void *sharetab,
3954
3763
int sharemax, zfs_share_op_t operation)
4115
3926
return (error);
3930
zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
3931
boolean_t recursive, boolean_t temphold, boolean_t enoent_ok)
3933
zfs_cmd_t zc = { 0 };
3934
libzfs_handle_t *hdl = zhp->zfs_hdl;
3936
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3937
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3938
if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
3939
>= sizeof (zc.zc_string))
3940
return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
3941
zc.zc_cookie = recursive;
3942
zc.zc_temphold = temphold;
3944
if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) {
3945
char errbuf[ZFS_MAXNAMELEN+32];
3948
* if it was recursive, the one that actually failed will be in
3951
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3952
"cannot hold '%s@%s'"), zc.zc_name, snapname);
3956
* Temporary tags wind up having the ds object id
3957
* prepended. So even if we passed the length check
3958
* above, it's still possible for the tag to wind
3959
* up being slightly too long.
3961
return (zfs_error(hdl, EZFS_TAGTOOLONG, errbuf));
3963
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3964
"pool must be upgraded"));
3965
return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3967
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3969
return (zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf));
3975
return (zfs_standard_error_fmt(hdl, errno, errbuf));
3982
struct hold_range_arg {
3983
zfs_handle_t *origin;
3984
const char *fromsnap;
3986
char lastsnapheld[ZFS_MAXNAMELEN];
3992
boolean_t recursive;
3993
snapfilter_cb_t *filter_cb;
3994
void *filter_cb_arg;
3998
zfs_hold_range_one(zfs_handle_t *zhp, void *arg)
4000
struct hold_range_arg *hra = arg;
4001
const char *thissnap;
4004
thissnap = strchr(zfs_get_name(zhp), '@') + 1;
4006
if (hra->fromsnap && !hra->seenfrom &&
4007
strcmp(hra->fromsnap, thissnap) == 0)
4008
hra->seenfrom = B_TRUE;
4010
/* snap is older or newer than the desired range, ignore it */
4011
if (hra->seento || !hra->seenfrom) {
4016
if (!hra->seento && strcmp(hra->tosnap, thissnap) == 0)
4017
hra->seento = B_TRUE;
4019
if (hra->filter_cb != NULL &&
4020
hra->filter_cb(zhp, hra->filter_cb_arg) == B_FALSE) {
4026
/* We could be racing with destroy, so ignore ENOENT. */
4027
error = zfs_hold(hra->origin, thissnap, hra->tag,
4028
hra->recursive, hra->temphold, B_TRUE);
4030
(void) strlcpy(hra->lastsnapheld, zfs_get_name(zhp),
4031
sizeof (hra->lastsnapheld));
4034
error = zfs_release(hra->origin, thissnap, hra->tag,
4043
* Add a user hold on the set of snapshots starting with fromsnap up to
4044
* and including tosnap. If we're unable to to acquire a particular hold,
4045
* undo any holds up to that point.
4048
zfs_hold_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
4049
const char *tag, boolean_t recursive, boolean_t temphold,
4050
snapfilter_cb_t filter_cb, void *cbarg)
4052
struct hold_range_arg arg = { 0 };
4056
arg.fromsnap = fromsnap;
4057
arg.tosnap = tosnap;
4059
arg.temphold = temphold;
4060
arg.holding = B_TRUE;
4061
arg.recursive = recursive;
4062
arg.seenfrom = (fromsnap == NULL);
4063
arg.filter_cb = filter_cb;
4064
arg.filter_cb_arg = cbarg;
4066
error = zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg);
4069
* Make sure we either hold the entire range or none.
4071
if (error && arg.lastsnapheld[0] != '\0') {
4072
(void) zfs_release_range(zhp, fromsnap,
4073
(const char *)arg.lastsnapheld, tag, recursive);
4079
zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4080
boolean_t recursive)
4082
zfs_cmd_t zc = { 0 };
4083
libzfs_handle_t *hdl = zhp->zfs_hdl;
4085
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4086
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
4087
if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
4088
>= sizeof (zc.zc_string))
4089
return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
4090
zc.zc_cookie = recursive;
4092
if (zfs_ioctl(hdl, ZFS_IOC_RELEASE, &zc) != 0) {
4093
char errbuf[ZFS_MAXNAMELEN+32];
4096
* if it was recursive, the one that actually failed will be in
4099
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4100
"cannot release '%s' from '%s@%s'"), tag, zc.zc_name,
4104
return (zfs_error(hdl, EZFS_REFTAG_RELE, errbuf));
4106
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4107
"pool must be upgraded"));
4108
return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
4110
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4112
return (zfs_standard_error_fmt(hdl, errno, errbuf));
4120
* Release a user hold from the set of snapshots starting with fromsnap
4121
* up to and including tosnap.
4124
zfs_release_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
4125
const char *tag, boolean_t recursive)
4127
struct hold_range_arg arg = { 0 };
4130
arg.fromsnap = fromsnap;
4131
arg.tosnap = tosnap;
4133
arg.recursive = recursive;
4134
arg.seenfrom = (fromsnap == NULL);
4136
return (zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg));
4140
zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
4143
uint64_t nblocks, volblocksize;
4147
if (nvlist_lookup_string(props,
4148
zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
4149
ncopies = atoi(strval);
4152
if (nvlist_lookup_uint64(props,
4153
zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
4154
&volblocksize) != 0)
4155
volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
4156
nblocks = volsize/volblocksize;
4157
/* start with metadnode L0-L6 */
4159
/* calculate number of indirects */
4160
while (nblocks > 1) {
4161
nblocks += DNODES_PER_LEVEL - 1;
4162
nblocks /= DNODES_PER_LEVEL;
4165
numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
4168
* this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
4169
* compressed, but in practice they compress down to about
4172
numdb *= 1ULL << DN_MAX_INDBLKSHIFT;