libzfs_dataset.c revision ece3d9b3bacef51a5f34d993935eedbb7bb87059
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
99653d4ee642c6528e88224f12409a5f23060994eschrock * Given a single type (not a mask of types), return the type in a human
99653d4ee642c6528e88224f12409a5f23060994eschrock * readable form.
99653d4ee642c6528e88224f12409a5f23060994eschrockconst char *
99653d4ee642c6528e88224f12409a5f23060994eschrock * Given a path and mask of ZFS types, return a string describing this dataset.
99653d4ee642c6528e88224f12409a5f23060994eschrock * This is used when we fail to open a dataset and we cannot get an exact type.
99653d4ee642c6528e88224f12409a5f23060994eschrock * We guess what the type would have been based on the path and the mask of
99653d4ee642c6528e88224f12409a5f23060994eschrock * acceptable types.
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic const char *
99653d4ee642c6528e88224f12409a5f23060994eschrock * When given a single type, always report the exact type.
99653d4ee642c6528e88224f12409a5f23060994eschrock * The user is requesting more than one type of dataset. If this is the
99653d4ee642c6528e88224f12409a5f23060994eschrock * case, consult the path itself. If we're looking for a snapshot, and
99653d4ee642c6528e88224f12409a5f23060994eschrock * a '@' is found, then report it as "snapshot". Otherwise, remove the
99653d4ee642c6528e88224f12409a5f23060994eschrock * snapshot attribute and try again.
99653d4ee642c6528e88224f12409a5f23060994eschrock return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
99653d4ee642c6528e88224f12409a5f23060994eschrock * The user has requested either filesystems or volumes.
99653d4ee642c6528e88224f12409a5f23060994eschrock * We have no way of knowing a priori what type this would be, so always
99653d4ee642c6528e88224f12409a5f23060994eschrock * report it as "filesystem" or "volume", our two primitive types.
99653d4ee642c6528e88224f12409a5f23060994eschrock * Validate a ZFS path. This is used even before trying to open the dataset, to
99653d4ee642c6528e88224f12409a5f23060994eschrock * provide a more meaningful error message. We place a more useful message in
99653d4ee642c6528e88224f12409a5f23060994eschrock * 'buf' detailing exactly why the name was not valid.
99653d4ee642c6528e88224f12409a5f23060994eschrockzfs_validate_name(libzfs_handle_t *hdl, const char *path, int type)
99653d4ee642c6528e88224f12409a5f23060994eschrock "name is too long"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "leading slash in name"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "empty component in name"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "trailing slash in name"));
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl "multiple '@' delimiters in name"));
c08432ebe688ed6410b302771a9afd8e23e2a7cceschrock "pool doesn't begin with a letter"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "name is reserved"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "reserved disk name"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock "snapshot delimiter '@' in filesystem name"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock "missing '@' delimeter in snapshot name"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock * This function takes the raw DSL properties, and filters out the user-defined
fa9e4066f08beec538e775443c5be79dd423fcabahrens * properties into a separate nvlist.
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling if (nvlist_alloc(&zhp->zfs_user_props, NV_UNIQUE_NAME, 0) != 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock * Utility function to gather stats (objset and zpl) for the given object.
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (-1);
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (-1);
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling zhp->zfs_dmustats = zc.zc_objset_stats; /* structure assignment */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zhp->zfs_root, zc.zc_value, sizeof (zhp->zfs_root));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zfs_props) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock * Refresh the properties currently stored in the handle.
99653d4ee642c6528e88224f12409a5f23060994eschrock * Makes a handle from the given dataset name. Used by zfs_open() and
99653d4ee642c6528e88224f12409a5f23060994eschrock * zfs_iter_* to create child handles on the fly.
99653d4ee642c6528e88224f12409a5f23060994eschrockmake_dataset_handle(libzfs_handle_t *hdl, const char *path)
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
99653d4ee642c6528e88224f12409a5f23060994eschrock * If it is dds_inconsistent, then we've caught it in
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling * the middle of a 'zfs receive' or 'zfs destroy', and
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it is inconsistent from the ZPL's point of view, so
99653d4ee642c6528e88224f12409a5f23060994eschrock * can't be mounted. However, it could also be that we
99653d4ee642c6528e88224f12409a5f23060994eschrock * have crashed in the middle of one of those
99653d4ee642c6528e88224f12409a5f23060994eschrock * operations, in which case we need to get rid of the
99653d4ee642c6528e88224f12409a5f23060994eschrock * inconsistent state. We do that by either rolling
99653d4ee642c6528e88224f12409a5f23060994eschrock * back to the previous snapshot (which will fail if
99653d4ee642c6528e88224f12409a5f23060994eschrock * there is none), or destroying the filesystem. Note
99653d4ee642c6528e88224f12409a5f23060994eschrock * that if we are still in the middle of an active
99653d4ee642c6528e88224f12409a5f23060994eschrock * 'receive' or 'destroy', then the rollback and destroy
99653d4ee642c6528e88224f12409a5f23060994eschrock * will fail with EBUSY and we will drive on as usual.
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
99653d4ee642c6528e88224f12409a5f23060994eschrock /* If we can successfully roll it back, reget the stats */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock * If we can sucessfully destroy it, pretend that it
99653d4ee642c6528e88224f12409a5f23060994eschrock * never existed.
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock * We've managed to open the dataset and gather statistics. Determine
99653d4ee642c6528e88224f12409a5f23060994eschrock * the high-level type.
99653d4ee642c6528e88224f12409a5f23060994eschrock else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Opens the given snapshot, filesystem, or volume. The 'types'
fa9e4066f08beec538e775443c5be79dd423fcabahrens * argument is a mask of acceptable types. The function will print an
fa9e4066f08beec538e775443c5be79dd423fcabahrens * appropriate error message and return NULL if it can't be opened.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_open(libzfs_handle_t *hdl, const char *path, int types)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * Validate the name before we even try to open it.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "invalid dataset name"));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * Try to get stats for the dataset, which will tell us if it exists.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Release a ZFS handle. Nothing to do but free the associated memory.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a numeric suffix, convert the value into a number of bits that the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * resulting value must be shifted.
5c7098917783942b65876f681a21342761227dadeschrock return (0);
5c7098917783942b65876f681a21342761227dadeschrock return (-1);
5c7098917783942b65876f681a21342761227dadeschrock * We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't
5c7098917783942b65876f681a21342761227dadeschrock * allow 'BB' - that's just weird.
5c7098917783942b65876f681a21342761227dadeschrock if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
5c7098917783942b65876f681a21342761227dadeschrock return (10*i);
5c7098917783942b65876f681a21342761227dadeschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock * Convert a string of the form '100G' into a real number. Used when setting
99653d4ee642c6528e88224f12409a5f23060994eschrock * properties or creating a volume. 'buf' is used to place an extended error
99653d4ee642c6528e88224f12409a5f23060994eschrock * message for the caller to use.
99653d4ee642c6528e88224f12409a5f23060994eschrocknicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
99653d4ee642c6528e88224f12409a5f23060994eschrock /* Check to see if this looks like a number. */
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock /* Rely on stroll() to process the numeric portion. */
99653d4ee642c6528e88224f12409a5f23060994eschrock * Check for ERANGE, which indicates that the value is too large to fit
99653d4ee642c6528e88224f12409a5f23060994eschrock * in a 64-bit value.
99653d4ee642c6528e88224f12409a5f23060994eschrock "numeric value is too large"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock * If we have a decimal value, then do the computation with floating
99653d4ee642c6528e88224f12409a5f23060994eschrock * point arithmetic. Otherwise, use standard arithmetic.
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock "numeric value is too large"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
5aba80db367b061758a29154d304977d00d8e4f4ck return (-1);
5aba80db367b061758a29154d304977d00d8e4f4ck /* Check for overflow */
5aba80db367b061758a29154d304977d00d8e4f4ck "numeric value is too large"));
5aba80db367b061758a29154d304977d00d8e4f4ck return (-1);
5aba80db367b061758a29154d304977d00d8e4f4ck return (0);
5aba80db367b061758a29154d304977d00d8e4f4ckzfs_nicestrtonum(libzfs_handle_t *hdl, const char *str, uint64_t *val)
5aba80db367b061758a29154d304977d00d8e4f4ck * The prop_parse_*() functions are designed to allow flexibility in callers
5aba80db367b061758a29154d304977d00d8e4f4ck * when setting properties. At the DSL layer, all properties are either 64-bit
5aba80db367b061758a29154d304977d00d8e4f4ck * numbers or strings. We want the user to be able to ignore this fact and
5aba80db367b061758a29154d304977d00d8e4f4ck * specify properties as native values (boolean, for example) or as strings (to
5aba80db367b061758a29154d304977d00d8e4f4ck * simplify command line utilities). This also handles converting index types
5aba80db367b061758a29154d304977d00d8e4f4ck * (compression, checksum, etc) from strings to their on-disk index.
5aba80db367b061758a29154d304977d00d8e4f4ckprop_parse_boolean(libzfs_handle_t *hdl, nvpair_t *elem, uint64_t *val)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "property '%s' must be 'on' or 'off'"),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "'%s' must be a boolean value"),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock VERIFY(nvpair_value_boolean_value(elem, &value) == 0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "'%s' must be a boolean value"),
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrens return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrockprop_parse_number(libzfs_handle_t *hdl, nvpair_t *elem, zfs_prop_t prop,
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "'%s' must be a number"),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * Quota special: force 'none' and don't allow 0.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (ret == 0 && !isnone && prop == ZFS_PROP_QUOTA) {
char *value;
static nvlist_t *
const char *propname;
char *strval;
return (NULL);
goto error;
propname);
goto error;
propname);
errbuf);
goto error;
propname);
errbuf);
goto error;
goto error;
goto error;
propname);
goto error;
case prop_type_boolean:
goto error;
case prop_type_string:
propname);
goto error;
goto error;
case prop_type_number:
goto error;
case prop_type_index:
goto error;
abort();
if (strval) {
goto error;
goto error;
switch (prop) {
case ZFS_PROP_RECORDSIZE:
case ZFS_PROP_VOLBLOCKSIZE:
goto error;
case ZFS_PROP_SHAREISCSI:
propname);
goto error;
case ZFS_PROP_MOUNTPOINT:
goto error;
case ZFS_PROP_SHARENFS:
* it can be set in a global/non-global zone based on
if (zoned) {
propname);
errbuf);
goto error;
errbuf);
goto error;
goto error;
switch (prop) {
case ZFS_PROP_RESERVATION:
errbuf);
goto error;
case ZFS_PROP_VOLSIZE:
sizeof (buf));
errbuf);
goto error;
if (intval == 0) {
propname);
errbuf);
goto error;
&intval) == 0) {
&new_reservation) != 0) {
intval) != 0) {
goto error;
return (ret);
return (NULL);
goto error;
goto error;
goto error;
goto error;
goto error;
goto error;
if (ret != 0) {
switch (errno) {
case ENOSPC:
switch (prop) {
case ZFS_PROP_QUOTA:
case ZFS_PROP_RESERVATION:
case EBUSY:
case EROFS:
case EOVERFLOW:
#ifdef _ILP32
if (cl)
return (ret);
int ret;
goto error;
goto error;
goto error;
return (ret);
if (value)
static uint64_t
return (value);
char *value;
return (value);
switch (prop) {
case ZFS_PROP_ATIME:
if (src)
if (src)
case ZFS_PROP_DEVICES:
if (src)
if (src)
case ZFS_PROP_EXEC:
if (src)
if (src)
case ZFS_PROP_RECORDSIZE:
case ZFS_PROP_COMPRESSION:
case ZFS_PROP_ZONED:
case ZFS_PROP_CREATION:
case ZFS_PROP_COMPRESSRATIO:
case ZFS_PROP_REFERENCED:
case ZFS_PROP_USED:
case ZFS_PROP_CREATETXG:
case ZFS_PROP_AVAILABLE:
case ZFS_PROP_VOLSIZE:
case ZFS_PROP_VOLBLOCKSIZE:
case ZFS_PROP_READONLY:
if (src)
if (src)
case ZFS_PROP_QUOTA:
case ZFS_PROP_RESERVATION:
if (*val == 0)
case ZFS_PROP_SETUID:
if (src)
if (src)
case ZFS_PROP_MOUNTED:
case ZFS_PROP_CANMOUNT:
case ZFS_PROP_XATTR:
if (src)
if (src)
char *str;
const char *root;
const char *strval;
if (src)
switch (prop) {
case ZFS_PROP_ATIME:
case ZFS_PROP_READONLY:
case ZFS_PROP_SETUID:
case ZFS_PROP_ZONED:
case ZFS_PROP_DEVICES:
case ZFS_PROP_EXEC:
case ZFS_PROP_CANMOUNT:
case ZFS_PROP_XATTR:
case ZFS_PROP_AVAILABLE:
case ZFS_PROP_RECORDSIZE:
case ZFS_PROP_CREATETXG:
case ZFS_PROP_REFERENCED:
case ZFS_PROP_USED:
case ZFS_PROP_VOLSIZE:
case ZFS_PROP_VOLBLOCKSIZE:
if (literal)
case ZFS_PROP_COMPRESSION:
case ZFS_PROP_CHECKSUM:
case ZFS_PROP_SNAPDIR:
case ZFS_PROP_ACLMODE:
case ZFS_PROP_ACLINHERIT:
case ZFS_PROP_CREATION:
struct tm t;
if (literal ||
case ZFS_PROP_MOUNTPOINT:
relpath++;
str++;
relpath);
case ZFS_PROP_SHARENFS:
case ZFS_PROP_SHAREISCSI:
case ZFS_PROP_ISCSIOPTIONS:
proplen);
case ZFS_PROP_ORIGIN:
proplen);
case ZFS_PROP_QUOTA:
case ZFS_PROP_RESERVATION:
if (val == 0) {
if (literal)
if (literal)
case ZFS_PROP_COMPRESSRATIO:
case ZFS_PROP_TYPE:
case ZFS_TYPE_FILESYSTEM:
case ZFS_TYPE_VOLUME:
case ZFS_TYPE_SNAPSHOT:
abort();
case ZFS_PROP_MOUNTED:
if (val)
case ZFS_PROP_NAME:
abort();
char *source;
return (val);
char *source;
if (src)
int ret;
return (ret);
int ret;
&zc) == 0;
return (ret);
int ret;
return (ret);
char *loc;
char *slash;
path);
switch (errno) {
case ENOENT:
int ret;
&blocksize)) != 0) {
if (size == 0) {
if (props &&
if (ret != 0) {
switch (errno) {
case ENOENT:
case EINVAL:
case EDOM:
#ifdef _ILP32
case EOVERFLOW:
errbuf));
struct destroydata {
char *snapname;
if (szhp) {
int ret;
if (ret != 0) {
switch (errno) {
case EEXIST:
errbuf));
int ret;
if (props) {
if (ret != 0) {
switch (errno) {
case ENOENT:
case EXDEV:
errbuf));
errbuf));
return (ret);
typedef struct promote_data {
const char *cb_target;
const char *cb_errbuf;
char *cp;
int ret;
if (ret != 0) {
if (ret != 0) {
switch (save_errno) {
case EEXIST:
parent);
return (ret);
int ret;
return (ret);
const char *delim;
char *parent;
int ret;
if (ret != 0) {
&zc);
if (ret != 0)
return (ret);
int ret;
if (fromsnap)
if (ret != 0) {
switch (errno) {
case EXDEV:
case EDQUOT:
case EFBIG:
case EIO:
case ENOLINK:
case ENOSPC:
case ENOSTR:
case ENXIO:
case EPIPE:
case ERANGE:
case EFAULT:
case EROFS:
return (ret);
zfs_handle_t *h;
char *cp;
if (h == NULL)
zfs_close(h);
const char *opname;
zfs_close(h);
NULL) != 0)
goto ancestorerr;
if (h == NULL)
goto ancestorerr;
goto ancestorerr;
if (zfs_share(h) != 0)
goto ancestorerr;
zfs_close(h);
char *cp;
bytes = 0;
} while (size > 0);
if (isprefix) {
zfs_handle_t *h;
if (h == NULL)
if (!dryrun) {
zfs_close(h);
if (verbose) {
if (dryrun)
if (ioctl_err != 0) {
switch (errno) {
case ENODEV:
case ETXTBSY:
case EEXIST:
case EINVAL:
case ECKSUM:
zfs_handle_t *h;
zfs_close(h);
if (verbose) {
if (delta == 0)
typedef struct rollback_data {
int cb_error;
cbp) != 0)
int ret;
&zc)) != 0) {
return (ret);
int ret;
goto out;
goto out;
if (ret != 0) {
goto out;
out:
return (ret);
char **dependents;
int ret = 0;
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
return (ret);
int ret;
char *delim;
sizeof (parent));
errbuf));
goto error;
goto error;
return (ret);
switch (errno) {
case EEXIST:
switch (errno) {
case ENXIO:
nvlist_t *
s = fields;
p = s + len;
len = p - s;
if (len == 0) {
c = s[len];
for (i = 0; i < ZFS_NPROP_ALL; i++) {
char *strval;