diff options
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r-- | module/zfs/zfs_ioctl.c | 380 |
1 files changed, 310 insertions, 70 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index c6b55d24f..2b67761fd 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -176,6 +176,7 @@ #include <sys/dsl_deleg.h> #include <sys/dmu_objset.h> #include <sys/dmu_impl.h> +#include <sys/dmu_redact.h> #include <sys/dmu_tx.h> #include <sys/sunddi.h> #include <sys/policy.h> @@ -194,6 +195,7 @@ #include <sys/dmu_recv.h> #include <sys/dmu_send.h> +#include <sys/dmu_recv.h> #include <sys/dsl_destroy.h> #include <sys/dsl_bookmark.h> #include <sys/dsl_userhold.h> @@ -271,7 +273,8 @@ typedef struct zfs_ioc_key { typedef enum { NO_NAME, POOL_NAME, - DATASET_NAME + DATASET_NAME, + ENTITY_NAME } zfs_ioc_namecheck_t; typedef enum { @@ -3709,6 +3712,37 @@ zfs_ioc_get_bookmarks(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) } /* + * innvl is not used. + * + * outnvl: { + * property 1, property 2, ... + * } + * + */ +static const zfs_ioc_key_t zfs_keys_get_bookmark_props[] = { + /* no nvl keys */ +}; + +/* ARGSUSED */ +static int +zfs_ioc_get_bookmark_props(const char *bookmark, nvlist_t *innvl, + nvlist_t *outnvl) +{ + char fsname[ZFS_MAX_DATASET_NAME_LEN]; + char *bmname; + + bmname = strchr(bookmark, '#'); + if (bmname == NULL) + return (SET_ERROR(EINVAL)); + bmname++; + + (void) strlcpy(fsname, bookmark, sizeof (fsname)); + *(strchr(fsname, '#')) = '\0'; + + return (dsl_get_bookmark_props(fsname, bmname, outnvl)); +} + +/* * innvl: { * bookmark name 1, bookmark name 2 * } @@ -4112,6 +4146,40 @@ recursive_unmount(const char *fsname, void *arg) } /* + * + * snapname is the snapshot to redact. + * innvl: { + * "bookname" -> (string) + * name of the redaction bookmark to generate + * "snapnv" -> (nvlist, values ignored) + * snapshots to redact snapname with respect to + * } + * + * outnvl is unused + */ + +/* ARGSUSED */ +static const zfs_ioc_key_t zfs_keys_redact[] = { + {"bookname", DATA_TYPE_STRING, 0}, + {"snapnv", DATA_TYPE_NVLIST, 0}, +}; +static int +zfs_ioc_redact(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) +{ + nvlist_t *redactnvl = NULL; + char *redactbook = NULL; + + if (nvlist_lookup_nvlist(innvl, "snapnv", &redactnvl) != 0) + return (SET_ERROR(EINVAL)); + if (fnvlist_num_pairs(redactnvl) == 0) + return (SET_ERROR(ENXIO)); + if (nvlist_lookup_string(innvl, "bookname", &redactbook) != 0) + return (SET_ERROR(EINVAL)); + + return (dmu_redact_snap(snapname, redactnvl, redactbook)); +} + +/* * inputs: * zc_name old name of dataset * zc_value new name of dataset @@ -4626,6 +4694,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops, nvlist_t *origprops = NULL; /* existing properties */ nvlist_t *origrecvd = NULL; /* existing received properties */ boolean_t first_recvd_props = B_FALSE; + boolean_t tofs_was_redacted; file_t *input_fp; *read_bytes = 0; @@ -4636,10 +4705,13 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops, if (input_fp == NULL) return (SET_ERROR(EBADF)); + off = input_fp->f_offset; error = dmu_recv_begin(tofs, tosnap, begin_record, force, - resumable, localprops, hidden_args, origin, &drc); + resumable, localprops, hidden_args, origin, &drc, input_fp->f_vnode, + &off); if (error != 0) goto out; + tofs_was_redacted = dsl_get_redacted(drc.drc_ds); /* * Set properties before we receive the stream so that they are applied @@ -4740,9 +4812,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops, nvlist_free(xprops); } - off = input_fp->f_offset; - error = dmu_recv_stream(&drc, input_fp->f_vnode, &off, cleanup_fd, - action_handle); + error = dmu_recv_stream(&drc, cleanup_fd, action_handle, &off); if (error == 0) { zfsvfs_t *zfsvfs = NULL; @@ -4752,6 +4822,9 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops, /* online recv */ dsl_dataset_t *ds; int end_err; + boolean_t stream_is_redacted = DMU_GET_FEATUREFLAGS( + begin_record->drr_u.drr_begin. + drr_versioninfo) & DMU_BACKUP_FEATURE_REDACTED; ds = dmu_objset_ds(zfsvfs->z_os); error = zfs_suspend_fs(zfsvfs); @@ -4760,8 +4833,17 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops, * likely also fail, and clean up after itself. */ end_err = dmu_recv_end(&drc, zfsvfs); - if (error == 0) + /* + * If the dataset was not redacted, but we received a + * redacted stream onto it, we need to unmount the + * dataset. Otherwise, resume the filesystem. + */ + if (error == 0 && !drc.drc_newfs && + stream_is_redacted && !tofs_was_redacted) { + error = zfs_end_fs(zfsvfs, ds); + } else if (error == 0) { error = zfs_resume_fs(zfsvfs, ds); + } error = error ? error : end_err; deactivate_super(zfsvfs->z_sb); } else if ((zv = zvol_suspend(tofs)) != NULL) { @@ -5118,6 +5200,49 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) return (error); } +typedef struct dump_bytes_io { + vnode_t *dbi_vp; + void *dbi_buf; + int dbi_len; + int dbi_err; +} dump_bytes_io_t; + +static void +dump_bytes_cb(void *arg) +{ + dump_bytes_io_t *dbi = (dump_bytes_io_t *)arg; + ssize_t resid; /* have to get resid to get detailed errno */ + + dbi->dbi_err = vn_rdwr(UIO_WRITE, dbi->dbi_vp, + (caddr_t)dbi->dbi_buf, dbi->dbi_len, + 0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid); +} + +static int +dump_bytes(objset_t *os, void *buf, int len, void *arg) +{ + dump_bytes_io_t dbi; + + dbi.dbi_vp = arg; + dbi.dbi_buf = buf; + dbi.dbi_len = len; + +#if defined(HAVE_LARGE_STACKS) + dump_bytes_cb(&dbi); +#else + /* + * The vn_rdwr() call is performed in a taskq to ensure that there is + * always enough stack space to write safely to the target filesystem. + * The ZIO_TYPE_FREE threads are used because there can be a lot of + * them and they are used in vdev_file.c for a similar purpose. + */ + spa_taskq_dispatch_sync(dmu_objset_spa(os), ZIO_TYPE_FREE, + ZIO_TASKQ_ISSUE, dump_bytes_cb, &dbi, TQ_SLEEP); +#endif /* HAVE_LARGE_STACKS */ + + return (dbi.dbi_err); +} + /* * inputs: * zc_name name of snapshot to send @@ -5193,8 +5318,8 @@ zfs_ioc_send(zfs_cmd_t *zc) } } - error = dmu_send_estimate(tosnap, fromsnap, compressok || rawok, - &zc->zc_objset_type); + error = dmu_send_estimate_fast(tosnap, fromsnap, NULL, + compressok || rawok, &zc->zc_objset_type); if (fromsnap != NULL) dsl_dataset_rele(fromsnap, FTAG); @@ -5206,9 +5331,13 @@ zfs_ioc_send(zfs_cmd_t *zc) return (SET_ERROR(EBADF)); off = fp->f_offset; + dmu_send_outparams_t out = {0}; + out.dso_outfunc = dump_bytes; + out.dso_arg = fp->f_vnode; + out.dso_dryrun = B_FALSE; error = dmu_send_obj(zc->zc_name, zc->zc_sendobj, zc->zc_fromobj, embedok, large_block_ok, compressok, rawok, - zc->zc_cookie, fp->f_vnode, &off); + zc->zc_cookie, &off, &out); if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) fp->f_offset = off; @@ -5219,18 +5348,19 @@ zfs_ioc_send(zfs_cmd_t *zc) /* * inputs: - * zc_name name of snapshot on which to report progress - * zc_cookie file descriptor of send stream + * zc_name name of snapshot on which to report progress + * zc_cookie file descriptor of send stream * * outputs: - * zc_cookie number of bytes written in send stream thus far + * zc_cookie number of bytes written in send stream thus far + * zc_objset_type logical size of data traversed by send thus far */ static int zfs_ioc_send_progress(zfs_cmd_t *zc) { dsl_pool_t *dp; dsl_dataset_t *ds; - dmu_sendarg_t *dsp = NULL; + dmu_sendstatus_t *dsp = NULL; int error; error = dsl_pool_hold(zc->zc_name, FTAG, &dp); @@ -5254,15 +5384,19 @@ zfs_ioc_send_progress(zfs_cmd_t *zc) for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL; dsp = list_next(&ds->ds_sendstreams, dsp)) { - if (dsp->dsa_outfd == zc->zc_cookie && - dsp->dsa_proc->group_leader == curproc->group_leader) + if (dsp->dss_outfd == zc->zc_cookie && + dsp->dss_proc == curproc) break; } - if (dsp != NULL) - zc->zc_cookie = *(dsp->dsa_off); - else + if (dsp != NULL) { + zc->zc_cookie = atomic_cas_64((volatile uint64_t *)dsp->dss_off, + 0, 0); + /* This is the closest thing we have to atomic_read_64. */ + zc->zc_objset_type = atomic_cas_64(&dsp->dss_blocks, 0, 0); + } else { error = SET_ERROR(ENOENT); + } mutex_exit(&ds->ds_sendstream_lock); dsl_dataset_rele(ds, FTAG); @@ -5973,8 +6107,8 @@ zfs_ioc_events_seek(zfs_cmd_t *zc) /* * inputs: - * zc_name name of new filesystem or snapshot - * zc_value full name of old snapshot + * zc_name name of later filesystem or snapshot + * zc_value full name of old snapshot or bookmark * * outputs: * zc_cookie space in bytes @@ -5986,7 +6120,7 @@ zfs_ioc_space_written(zfs_cmd_t *zc) { int error; dsl_pool_t *dp; - dsl_dataset_t *new, *old; + dsl_dataset_t *new; error = dsl_pool_hold(zc->zc_name, FTAG, &dp); if (error != 0) @@ -5996,16 +6130,26 @@ zfs_ioc_space_written(zfs_cmd_t *zc) dsl_pool_rele(dp, FTAG); return (error); } - error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old); - if (error != 0) { - dsl_dataset_rele(new, FTAG); - dsl_pool_rele(dp, FTAG); - return (error); - } + if (strchr(zc->zc_value, '#') != NULL) { + zfs_bookmark_phys_t bmp; + error = dsl_bookmark_lookup(dp, zc->zc_value, + new, &bmp); + if (error == 0) { + error = dsl_dataset_space_written_bookmark(&bmp, new, + &zc->zc_cookie, + &zc->zc_objset_type, &zc->zc_perm_action); + } + } else { + dsl_dataset_t *old; + error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old); - error = dsl_dataset_space_written(old, new, &zc->zc_cookie, - &zc->zc_objset_type, &zc->zc_perm_action); - dsl_dataset_rele(old, FTAG); + if (error == 0) { + error = dsl_dataset_space_written(old, new, + &zc->zc_cookie, + &zc->zc_objset_type, &zc->zc_perm_action); + dsl_dataset_rele(old, FTAG); + } + } dsl_dataset_rele(new, FTAG); dsl_pool_rele(dp, FTAG); return (error); @@ -6085,6 +6229,9 @@ zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl) * presence indicates raw encrypted records should be used. * (optional) "resume_object" and "resume_offset" -> (uint64) * if present, resume send stream from specified object and offset. + * (optional) "redactbook" -> (string) + * if present, use this bookmark's redaction list to generate a redacted + * send stream * } * * outnvl is unused @@ -6098,6 +6245,7 @@ static const zfs_ioc_key_t zfs_keys_send_new[] = { {"rawok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, {"resume_object", DATA_TYPE_UINT64, ZK_OPTIONAL}, {"resume_offset", DATA_TYPE_UINT64, ZK_OPTIONAL}, + {"redactbook", DATA_TYPE_STRING, ZK_OPTIONAL}, }; /* ARGSUSED */ @@ -6115,6 +6263,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) boolean_t rawok; uint64_t resumeobj = 0; uint64_t resumeoff = 0; + char *redactbook = NULL; fd = fnvlist_lookup_int32(innvl, "fd"); @@ -6128,12 +6277,18 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) (void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj); (void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff); + (void) nvlist_lookup_string(innvl, "redactbook", &redactbook); + if ((fp = getf(fd)) == NULL) return (SET_ERROR(EBADF)); off = fp->f_offset; + dmu_send_outparams_t out = {0}; + out.dso_outfunc = dump_bytes; + out.dso_arg = fp->f_vnode; + out.dso_dryrun = B_FALSE; error = dmu_send(snapname, fromname, embedok, largeblockok, compressok, - rawok, fd, resumeobj, resumeoff, fp->f_vnode, &off); + rawok, resumeobj, resumeoff, redactbook, fd, &off, &out); if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) fp->f_offset = off; @@ -6142,6 +6297,15 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) return (error); } +/* ARGSUSED */ +int +send_space_sum(objset_t *os, void *buf, int len, void *arg) +{ + uint64_t *size = arg; + *size += len; + return (0); +} + /* * Determine approximately how large a zfs send stream will be -- the number * of bytes that will be written to the fd supplied to zfs_ioc_send_new(). @@ -6157,6 +6321,8 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) * presence indicates compressed DRR_WRITE records are permitted * (optional) "rawok" -> (value ignored) * presence indicates raw encrypted records should be used. + * (optional) "fd" -> file descriptor to use as a cookie for progress + * tracking (int32) * } * * outnvl: { @@ -6170,6 +6336,11 @@ static const zfs_ioc_key_t zfs_keys_send_space[] = { {"embedok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, {"compressok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, {"rawok", DATA_TYPE_BOOLEAN, ZK_OPTIONAL}, + {"fd", DATA_TYPE_INT32, ZK_OPTIONAL}, + {"redactbook", DATA_TYPE_STRING, ZK_OPTIONAL}, + {"resumeobj", DATA_TYPE_UINT64, ZK_OPTIONAL}, + {"resumeoff", DATA_TYPE_UINT64, ZK_OPTIONAL}, + {"bytes", DATA_TYPE_UINT64, ZK_OPTIONAL}, }; static int @@ -6177,11 +6348,21 @@ zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) { dsl_pool_t *dp; dsl_dataset_t *tosnap; + dsl_dataset_t *fromsnap = NULL; int error; - char *fromname; + char *fromname = NULL; + char *redactlist_book = NULL; + boolean_t largeblockok; + boolean_t embedok; boolean_t compressok; boolean_t rawok; - uint64_t space; + uint64_t space = 0; + boolean_t full_estimate = B_FALSE; + uint64_t resumeobj = 0; + uint64_t resumeoff = 0; + uint64_t resume_bytes = 0; + int32_t fd = -1; + zfs_bookmark_phys_t zbm = {0}; error = dsl_pool_hold(snapname, FTAG, &dp); if (error != 0) @@ -6192,61 +6373,101 @@ zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) dsl_pool_rele(dp, FTAG); return (error); } + (void) nvlist_lookup_int32(innvl, "fd", &fd); + largeblockok = nvlist_exists(innvl, "largeblockok"); + embedok = nvlist_exists(innvl, "embedok"); compressok = nvlist_exists(innvl, "compressok"); rawok = nvlist_exists(innvl, "rawok"); + boolean_t from = (nvlist_lookup_string(innvl, "from", &fromname) == 0); + boolean_t altbook = (nvlist_lookup_string(innvl, "redactbook", + &redactlist_book) == 0); + + (void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj); + (void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff); + (void) nvlist_lookup_uint64(innvl, "bytes", &resume_bytes); + + if (altbook) { + full_estimate = B_TRUE; + } else if (from) { + if (strchr(fromname, '#')) { + error = dsl_bookmark_lookup(dp, fromname, tosnap, &zbm); - error = nvlist_lookup_string(innvl, "from", &fromname); - if (error == 0) { - if (strchr(fromname, '@') != NULL) { /* - * If from is a snapshot, hold it and use the more - * efficient dmu_send_estimate to estimate send space - * size using deadlists. + * dsl_bookmark_lookup() will fail with EXDEV if + * the from-bookmark and tosnap are at the same txg. + * However, it's valid to do a send (and therefore, + * a send estimate) from and to the same time point, + * if the bookmark is redacted (the incremental send + * can change what's redacted on the target). In + * this case, dsl_bookmark_lookup() fills in zbm + * but returns EXDEV. Ignore this error. */ - dsl_dataset_t *fromsnap; + if (error == EXDEV && zbm.zbm_redaction_obj != 0 && + zbm.zbm_guid == + dsl_dataset_phys(tosnap)->ds_guid) + error = 0; + + if (error != 0) { + dsl_dataset_rele(tosnap, FTAG); + dsl_pool_rele(dp, FTAG); + return (error); + } + if (zbm.zbm_redaction_obj != 0 || !(zbm.zbm_flags & + ZBM_FLAG_HAS_FBN)) { + full_estimate = B_TRUE; + } + } else if (strchr(fromname, '@')) { error = dsl_dataset_hold(dp, fromname, FTAG, &fromsnap); - if (error != 0) - goto out; - error = dmu_send_estimate(tosnap, fromsnap, - compressok || rawok, &space); - dsl_dataset_rele(fromsnap, FTAG); - } else if (strchr(fromname, '#') != NULL) { - /* - * If from is a bookmark, fetch the creation TXG of the - * snapshot it was created from and use that to find - * blocks that were born after it. - */ - zfs_bookmark_phys_t frombm; + if (error != 0) { + dsl_dataset_rele(tosnap, FTAG); + dsl_pool_rele(dp, FTAG); + return (error); + } - error = dsl_bookmark_lookup(dp, fromname, tosnap, - &frombm); - if (error != 0) - goto out; - error = dmu_send_estimate_from_txg(tosnap, - frombm.zbm_creation_txg, compressok || rawok, - &space); + if (!dsl_dataset_is_before(tosnap, fromsnap, 0)) { + full_estimate = B_TRUE; + dsl_dataset_rele(fromsnap, FTAG); + } } else { /* * from is not properly formatted as a snapshot or * bookmark */ - error = SET_ERROR(EINVAL); - goto out; + dsl_dataset_rele(tosnap, FTAG); + dsl_pool_rele(dp, FTAG); + return (SET_ERROR(EINVAL)); } - } else { + } + + if (full_estimate) { + dmu_send_outparams_t out = {0}; + offset_t off = 0; + out.dso_outfunc = send_space_sum; + out.dso_arg = &space; + out.dso_dryrun = B_TRUE; /* - * If estimating the size of a full send, use dmu_send_estimate. + * We have to release these holds so dmu_send can take them. It + * will do all the error checking we need. */ - error = dmu_send_estimate(tosnap, NULL, compressok || rawok, - &space); + dsl_dataset_rele(tosnap, FTAG); + dsl_pool_rele(dp, FTAG); + error = dmu_send(snapname, fromname, embedok, largeblockok, + compressok, rawok, resumeobj, resumeoff, redactlist_book, + fd, &off, &out); + } else { + error = dmu_send_estimate_fast(tosnap, fromsnap, + (from && strchr(fromname, '#') != NULL ? &zbm : NULL), + compressok || rawok, &space); + space -= resume_bytes; + if (fromsnap != NULL) + dsl_dataset_rele(fromsnap, FTAG); + dsl_dataset_rele(tosnap, FTAG); + dsl_pool_rele(dp, FTAG); } fnvlist_add_uint64(outnvl, "space", space); -out: - dsl_dataset_rele(tosnap, FTAG); - dsl_pool_rele(dp, FTAG); return (error); } @@ -6607,6 +6828,11 @@ zfs_ioctl_init(void) POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, zfs_keys_get_bookmarks, ARRAY_SIZE(zfs_keys_get_bookmarks)); + zfs_ioctl_register("get_bookmark_props", ZFS_IOC_GET_BOOKMARK_PROPS, + zfs_ioc_get_bookmark_props, zfs_secpolicy_read, ENTITY_NAME, + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE, zfs_keys_get_bookmark_props, + ARRAY_SIZE(zfs_keys_get_bookmark_props)); + zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS, zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks, POOL_NAME, @@ -6646,6 +6872,11 @@ zfs_ioctl_init(void) B_TRUE, zfs_keys_channel_program, ARRAY_SIZE(zfs_keys_channel_program)); + zfs_ioctl_register("redact", ZFS_IOC_REDACT, + zfs_ioc_redact, zfs_secpolicy_config, DATASET_NAME, + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, + zfs_keys_redact, ARRAY_SIZE(zfs_keys_redact)); + zfs_ioctl_register("zpool_checkpoint", ZFS_IOC_POOL_CHECKPOINT, zfs_ioc_pool_checkpoint, zfs_secpolicy_config, POOL_NAME, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE, @@ -6891,7 +7122,8 @@ pool_status_check(const char *name, zfs_ioc_namecheck_t type, spa_t *spa; int error; - ASSERT(type == POOL_NAME || type == DATASET_NAME); + ASSERT(type == POOL_NAME || type == DATASET_NAME || + type == ENTITY_NAME); if (check & POOL_CHECK_NONE) return (0); @@ -7162,10 +7394,18 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg) vec->zvec_namecheck, vec->zvec_pool_check); break; + case ENTITY_NAME: + if (entity_namecheck(zc->zc_name, NULL, NULL) != 0) { + error = SET_ERROR(EINVAL); + } else { + error = pool_status_check(zc->zc_name, + vec->zvec_namecheck, vec->zvec_pool_check); + } + break; + case NO_NAME: break; } - /* * Ensure that all input pairs are valid before we pass them down * to the lower layers. |