zfs_ioctl.c revision 971640e6aa954c91b0706543741aa4570299f4d7
0N/A * The contents of this file are subject to the terms of the 0N/A * Common Development and Distribution License (the "License"). 0N/A * You may not use this file except in compliance with the License. 0N/A * See the License for the specific language governing permissions 0N/A * and limitations under the License. 0N/A * When distributing Covered Code, include this CDDL HEADER in each 0N/A * If applicable, add the following below this CDDL HEADER, with the 0N/A * fields enclosed by brackets "[]" replaced with your own identifying 0N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2362N/A * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * Portions Copyright 2011 Martin Matuska 0N/A * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. 0N/A * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 0N/A * Copyright (c) 2014, Joyent, Inc. All rights reserved. 0N/A * Copyright (c) 2011, 2015 by Delphix. All rights reserved. 0N/A * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. 0N/A * Copyright (c) 2013 Steven Hartland. All rights reserved. 0N/A * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage * There are two ways that we handle ioctls: the legacy way where almost * all of the logic is in the ioctl callback, and the new way where most * of the marshalling is handled in the common entry point, zfsdev_ioctl(). * Non-legacy ioctls should be registered by calling * zfs_ioctl_register() from zfs_ioctl_init(). The ioctl is invoked * from userland by lzc_ioctl(). * The registration arguments are as follows: * The name of the ioctl. This is used for history logging. If the * ioctl returns successfully (the callback returns 0), and allow_log * is true, then a history log entry will be recorded with the input & * output nvlists. The log entry can be printed with "zpool history -i". * The ioctl request number, which userland will pass to ioctl(2). * The ioctl numbers can change from release to release, because * the caller (libzfs) must be matched to the kernel. * zfs_secpolicy_func_t *secpolicy * This function will be called before the zfs_ioc_func_t, to * determine if this operation is permitted. It should return EPERM * on failure, and 0 on success. Checks include determining if the * dataset is visible in this zone, and if the user has either all * zfs privileges in the zone (SYS_MOUNT), or has been granted permission * to do this operation on this dataset with "zfs allow". * zfs_ioc_namecheck_t namecheck * This specifies what to expect in the zfs_cmd_t:zc_name -- a pool * name, a dataset name, or nothing. If the name is not well-formed, * the ioctl will fail and the callback will not be called. * Therefore, the callback can assume that the name is well-formed * (e.g. is null-terminated, doesn't have more than one '@' character, * doesn't have invalid characters). * zfs_ioc_poolcheck_t pool_check * This specifies requirements on the pool state. If the pool does * not meet them (is suspended or is readonly), the ioctl will fail * and the callback will not be called. If any checks are specified * (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME. * Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED | * boolean_t smush_outnvlist * If smush_outnvlist is true, then the output is presumed to be a * list of errors, and it will be "smushed" down to fit into the * caller's buffer, by removing some entries and replacing them with a * single "N_MORE_ERRORS" entry indicating how many were removed. See * nvlist_smush() for details. If smush_outnvlist is false, and the * outnvlist does not fit into the userland-provided buffer, then the * ioctl will fail with ENOMEM. * The callback function that will perform the operation. * The callback should return 0 on success, or an error number on * failure. If the function fails, the userland ioctl will return -1, * and errno will be set to the callback's return value. The callback * will be called with the following arguments: * The name of the pool or dataset to operate on, from * zfs_cmd_t:zc_name. The 'namecheck' argument specifies the * expected type (pool, dataset, or none). * The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src. Or * NULL if no input nvlist was provided. Changes to this nvlist are * ignored. If the input nvlist could not be deserialized, the * ioctl will fail and the callback will not be called. * The output nvlist, initially empty. The callback can fill it in, * and it will be returned to userland by serializing it into * zfs_cmd_t:zc_nvlist_dst. If it is non-empty, and serialization * fails (e.g. because the caller didn't supply a large enough * buffer), then the overall ioctl will fail. See the * 'smush_nvlist' argument above for additional behaviors. * There are two typical uses of the output nvlist: * - To return state, e.g. property values. In this case, * smush_outnvlist should be false. If the buffer was not large * enough, the caller will reallocate a larger buffer and try * - To return multiple errors from an ioctl which makes on-disk * changes. In this case, smush_outnvlist should be true. * Ioctls which make on-disk modifications should generally not * use the outnvl if they succeed, because the caller can not * distinguish between the operation failing, and * deserialization failing. /* This array is indexed by zfs_userquota_prop_t */ /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ * Get rid of annoying "../common/" prefix to filename. * To get this data, use the zfs-dprintf probe as so: * dtrace -q -n 'zfs-dprintf \ * /stringof(arg0) == "dbuf.c"/ \ * {printf("%s: %s", stringof(arg1), stringof(arg3))}' * Check to see if the named dataset is currently defined as bootable * Return non-zero if the spa version is less than requested version. * Return TRUE if the ZPL version is less than requested version. /* XXX reading from non-owned objset */ * Policy for top-level read operations (list pools). Requires no privileges, * and can be used in the local zone, as there is no associated dataset. * Policy for dataset read operations (list children, get statistics). Requires * no privileges, but must be visible in the local zone. * The dataset must be visible by this zone -- check this first * so they don't see EPERM on something they shouldn't know about. * If the fs is zoned, only root can access it from the * If we are in a local zone, the 'zoned' property must be set. /* must be writable by this zone */ * Policy for setting the security label property. * Returns 0 for success, non-zero for access and other errors. /* First get the existing dataset label. */ /* The label must be translatable */ * In a non-global zone, disallow attempts to set a label that * doesn't match that of the zone; otherwise no other checks * For global-zone datasets (i.e., those whose zoned property is * "off", verify that the specified new label is valid for the * If the existing dataset label is nondefault, check if the * dataset is mounted (label cannot be changed while mounted). * Get the zfsvfs; if there isn't one, then the dataset isn't * mounted (or isn't a dataset, doesn't exist, ...). * Try to own the dataset; abort if there is any error, * (e.g., already mounted, in use, or other error). /* dataset currently has a default label */ * Check permissions for special properties. * Disallow setting of 'zoned' from within a local zone. * Unprivileged users are allowed to modify the * limit on things *under* (ie. contained by) * permission to set permissions will be evaluated later in * Generate the current snapshot name from the given objsetid, then /* Now make sure mntpnt and dataset are ZFS */ * Remove the @bla or /bla from the end of the name to get the parent. * Destroying snapshots with delegated permissions requires * descendant mount and destroy permissions. * Ignore any snapshots that don't exist (we consider * them "already destroyed"). Remove the name from the * nvl here in case the snapshot is created between * now and when we try to destroy it (in which case * we don't want to destroy it since we haven't * checked for permission). * Check for permission to create each snapshot in the nvlist. * Check for permission to create each snapshot in the nvlist. * Ignore any filesystems that don't exist (we consider * their bookmarks "already destroyed"). Remove * the name from the nvl here in case the filesystem * is created between now and when we try to destroy * the bookmark (in which case we don't want to * destroy it since we haven't checked for permission). * Even root must have a proper TSD so that we know what pool * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires * SYS_CONFIG privilege, which is not available in a local zone. * Policy for object to name lookups. * Policy for fault injection. Requires all privileges. * They are asking about a posix uid/gid. If it's * Policy for allowing temporary snapshots to be taken or released * A temporary snapshot is the same as a snapshot, * hold, destroy and release all rolled into one. * Delegated diff alone is sufficient that we allow this. * Returns the nvlist as specified by the user in the zfs_cmd_t. * Read in and unpack the user-supplied nvlist. * Reduce the size of this nvlist until it can be serialized in 'max' bytes. * Entries will be removed from the end of the nvlist, and one int32 entry * named "N_MORE_ERRORS" will be added indicating how many entries were * Find a zfsvfs_t for a mounted filesystem, or create our own, in which * case its z_vfs will be NULL, and it will be opened as the owner. * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER, * which prevents all vnode ops from running. * XXX we could probably try again, since the unmounting * thread should be just about to disassociate the * objset from the zfsvfs. * Set the remaining root properties * zc_name name of the pool * zc_nvlist_dst config nvlist * zc_nvlist_dst_size size of config nvlist * The config may be present even if 'error' is non-zero. * In this case we return success, and preserve the real errno * Try to import the given pool, returning pool stats as appropriate so that * user land knows which devices are available and overall pool health. * zc_name name of the pool * zc_cookie scan func (pool_scan_func_t) * zc_name name of filesystem * zc_value name of object /* XXX reading from objset not owned */ * zc_name name of filesystem * zc_stat stats on object * zc_value path to object /* XXX reading from objset not owned */ * A root pool with concatenated devices is not supported. * Thus, can not add a device to a root pool. * Intent log device can not be added to a rootpool because * during mountroot, zil is replayed, a seperated log device * can not be accessed during the mountroot time. * l2cache and spare devices are ok to be added to a rootpool. * zc_name name of the pool * zc_nvlist_conf nvlist of devices to remove * zc_cookie to stop the remove? * NB: zvol_get_stats() will read the objset contents, * which we aren't supposed to do with a * DS_MODE_USER hold, because it could be * inconsistent. So this is a bit of a workaround... * XXX reading with out owning * zc_name name of filesystem * zc_nvlist_dst_size size of buffer for property nvlist * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist * zc_name name of filesystem * zc_nvlist_dst_size size of buffer for property nvlist * zc_nvlist_dst received property nvlist * zc_nvlist_dst_size size of received property nvlist * Gets received properties (distinct from local properties on or after * SPA_VERSION_RECVD_PROPS) for callers who want to differentiate received from * Without this check, we would return local property values if the * caller has not already received properties on or after * SPA_VERSION_RECVD_PROPS. * zfs_get_zplprop() will either find a value or give us * the default value (if there is one). * zc_name name of filesystem * zc_nvlist_dst_size size of buffer for zpl property nvlist * zc_nvlist_dst zpl property nvlist * zc_nvlist_dst_size size of zpl property nvlist /* XXX reading without owning */ * NB: nvl_add_zplprop() will read the objset contents, * which we aren't supposed to do with a DS_MODE_USER * hold, because it could be inconsistent. * Skip over datasets that are not visible in this zone, * internal datasets (which have a $ in their name), and * temporary datasets (which have a % in their name). * zc_name name of filesystem * zc_nvlist_dst_size size of buffer for property nvlist * zc_name name of next filesystem * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist if (p ==
NULL || p[
1] !=
'\0')
* If it's an internal dataset (ie. with a '$' in its name), * don't try to get stats for it, otherwise we'll return ENOENT. /* We lost a race with destroy, get the next one. */ * zc_name name of filesystem * zc_nvlist_dst_size size of buffer for property nvlist * zc_name name of next snapshot * zc_nvlist_dst property nvlist * zc_nvlist_dst_size size of property nvlist * A dataset name of maximum length cannot have any snapshots, /* if we failed, undo the @ that we tacked on to zc_name */ * A correctly constructed propname is encoded as * userquota@<rid>-<domain>. * If the named property is one that has a special function to set its value, * return 0 on success and a positive error code on failure; otherwise if it is * not one of the special properties handled by this function, return -1. * XXX: It would be better for callers of the property interface if we handled * these special cases in dsl_prop.c (in the dsl layer). /* clearing the limit, just do it */ * Set err to -1 to force the zfs_set_prop_nvlist code down the * default path to set the value in the nvlist. * This function is best effort. If it fails to set any of the given properties, * it continues to set as many as it can and returns the last error * encountered. If the caller provides a non-NULL errlist, it will be filled in * with the list of names of all the properties that failed along with the * corresponding error numbers. * If every property is set successfully, zero is returned and errlist is not /* decode the property value */ /* Validate value type */ "unknown property type");
/* Validate permissions */ * For better performance we build up a list of * properties to set in a single transaction. * This may be a spurious error caused by * receiving quota and reservation out of order. * Try again in a second pass. * If this fails, we still want to set as many properties as we * can, so try setting them individually. * Check that all the properties are valid user properties. * Acts on local properties until the dataset has received * properties at least once on or after SPA_VERSION_RECVD_PROPS. * zc_name name of filesystem * zc_value name of property to set * zc_nvlist_src{_size} nvlist of properties to apply * zc_cookie received properties flag * zc_nvlist_dst{_size} error for each unapplied received property * zc_name name of filesystem * zc_value name of property to inherit * zc_cookie revert to received value if TRUE * zfs_prop_set_special() expects properties in the form of an return (
err);
/* special property already handled */ * Only check this in the non-received case. We want to allow * 'inherit -S' to revert non-inheritable properties like quota * and reservation to the received or default values even though * they are not considered inheritable. /* property name has been validated by zfs_secpolicy_inherit_prop() */ * If the only property is the configfile, then just do a spa_lookup() * to handle the faulted case. * If the pool is faulted, there may be properties we can still * get (such as altroot and cachefile), so attempt to get them * zc_name name of filesystem * zc_nvlist_src{_size} nvlist of delegated permissions * Verify nvlist is constructed correctly * If we don't have PRIV_SYS_MOUNT, then validate * that user is allowed to hand out each permission in * zc_name name of filesystem * zc_nvlist_src{_size} nvlist of delegated permissions * Search the vfs list for a specified resource. Returns a pointer to it * or NULL if no suitable entry is found. The caller of this routine * is responsible for releasing the returned vfs pointer. * os parent objset pointer (NULL if root fs) * fuids_ok fuids allowed in this version of the spa? * sa_ok SAs allowed in this version of the spa? * createprops list of properties requested by creator * zplprops values for the zplprops we attach to the master node object * is_ci true if requested file system will be purely case-insensitive * Determine the settings for utf8only, normalization and * casesensitivity. Specific values may have been requested by the * creator and/or we can inherit values from the parent dataset. If * the file system is of too early a vintage, a creator can not * request settings for these properties, even if the requested * setting is the default value. We don't actually want to create dsl * properties for these, so remove them from the source nvlist after * Pull out creator prop choices, if any. * If the zpl version requested is whacky or the file system * or pool is version is too "young" to support normalization * and the creator tried to set a value for one of the props, * Put the version in the zplprops * If we're normalizing, names must always be valid UTF-8 strings. * Open parent object set so we can inherit zplprop values. * "type" -> dmu_objset_type_t (int32) * (optional) "props" -> { prop -> value } * outnvl: propname -> error code (int32) * We have to have normalization and * case-folding flags correct when we do the * file system creation, so go figure them out * It would be nice to do this atomically. * "origin" -> name of origin snapshot * (optional) "props" -> { prop -> value } * outnvl: propname -> error code (int32) * It would be nice to do this atomically. * "snaps" -> { snapshot1, snapshot2 } * (optional) "props" -> { prop -> value (string) } * outnvl: snapshot -> error code (int32) * The snap name must contain an @, and the part after it must * contain only valid characters. * The snap must be in the specified pool. /* This must be the only snap of this fs. */ * innvl: "message" -> string * The poolname in the ioctl is not set, we get it from the TSD, * which was set at the end of the last successful ioctl that allows * logging. The secpolicy func already checked that it is set. * Only one log ioctl is allowed after each successful ioctl, so * The dp_config_rwlock must not be held when calling this, because the * unmount may need to write out data. * This function is best-effort. Callers must deal gracefully if it * remains mounted (or is remounted after this call). * Returns 0 if the argument is not a snapshot, or it is not currently a * filesystem, or we were able to unmount it. Returns error code otherwise. * Always force the unmount for snapshots. * When a clone is destroyed, its origin may also need to be destroyed, * in which case it must be unmounted. This routine will do that unmount * "snaps" -> { snapshot1, snapshot2 } * (optional boolean) "defer" * outnvl: snapshot -> error code (int32) * Create bookmarks. Bookmark names are of the form <fs>#<bmark>. * All bookmarks must be in the same pool. * bookmark1 -> snapshot1, bookmark2 -> snapshot2 * outnvl: bookmark -> error code (int32) * Verify the snapshot argument. /* Verify that the keys (bookmarks) are unique */ * property 1, property 2, ... * bookmark name 1 -> { property 1, property 2, ... }, * bookmark name 2 -> { property 1, property 2, ... } * bookmark name 1, bookmark name 2 * outnvl: bookmark -> error code (int32) * The bookmark name must contain an #, and the part after it * must contain only valid characters. * The bookmark must be in the specified pool. * zc_name name of dataset to destroy * zc_objset_type type of objset * zc_defer_destroy mark for deferred destroy * fsname is name of dataset to rollback (to most recent snapshot) * outnvl: "target" -> name of most recent snapshot * zc_name old name of dataset * zc_value new name of dataset * zc_cookie recursive flag (only valid for snapshots) /* snaps must be in same fs */ /* USERUSED and GROUPUSED are read-only */ * dsl_prop_get_all_impl() returns properties in this * Check that this value is valid for this pool version * If the user specified gzip compression, make sure * the SPA supports it. We ignore any errors here since * we'll catch them later. * If this is a bootable dataset then * verify that the compression algorithm * is supported for booting. We must return * something other than ENOTSUP since it * implies a downrev pool version. /* Record sizes above 128k need the feature to be enabled */ * If this is a bootable dataset then * the we don't allow large (>128K) blocks, * because GRUB doesn't support them. * We don't allow setting the property above 1MB, * unless the tunable has been changed. /* dedup feature version checks */ /* check prop value is enabled in features */ * Salted checksums are not supported on root pools. * Checks for a race condition to make sure we don't increment a feature flag * The callback invoked on feature activation in the sync task caused by * zfs_prop_activate_feature. * Activates a feature on a pool in response to a property setting. This * creates a new sync task which modifies the pool to reflect the feature /* EBUSY here indicates that the feature is already active */ * Removes properties from the given props list that fail permission checks * needed to clear them and to restore them in case of a receive error. For each * property, make sure we have both set and inherit permissions. * Returns the first error encountered if any permission checks fail. If the * caller provides a non-NULL errlist, it also gives the complete list of names * of all the properties that failed a permission check along with the * corresponding error numbers. The caller is responsible for freeing the * If every property checks out successfully, zero is returned and the list * pointed at by errlist is NULL. /* dsl_prop_get_all_impl() format */ * Remove properties from props if they are not going to change (as determined * by comparison with origprops). Remove them from origprops as well, since we * do not need to clear or restore properties that won't change. return;
/* all props need to be received */ goto next;
/* need to set received value */ /* don't clear the existing received value */ /* don't bother receiving the property */ * Extract properties that cannot be set PRIOR to the receipt of a dataset. * For example, refquota cannot be set until after the receipt of a dataset, * because in replication streams, an older/earlier snapshot may exceed the * refquota. We want to receive the older/earlier snapshot, but setting * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent * the older/earlier snapshot from being received (with EDQUOT). * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario. * libzfs will need to be judicious handling errors encountered by props * extracted by this function. * strcmp() is safe because zfs_prop_to_name() always returns * zc_name name of containing filesystem * zc_nvlist_src{_size} nvlist of properties to apply * zc_value name of snapshot to create * zc_string name of clone origin (if DRR_FLAG_CLONE) * zc_cookie file descriptor to recv from * zc_begin_record the BEGIN record of the stream (not byteswapped) * zc_cleanup_fd cleanup-on-exit file descriptor * zc_action_handle handle for this guid/ds mapping (or zero on first call) * zc_resumable if data is incomplete assume sender will resume * zc_cookie number of bytes read * zc_nvlist_dst{_size} error for each unapplied received property * zc_obj zprop_errflags_t * zc_action_handle handle for this guid/ds mapping * Set properties before we receive the stream so that they are applied * to the new data. Note that we must call dmu_recv_stream() if * dmu_recv_begin() succeeds. * If new received properties are supplied, they are to * completely replace the existing received properties, so stash * away the existing ones. * Don't bother writing a property if its value won't * change (and avoid the unnecessary security checks). * The first receive after SPA_VERSION_RECVD_PROPS is a * special case where we blow away all local properties * If the suspend fails, then the recv_end will * likely also fail, and clean up after itself. /* Set delayed properties now, after we're done receiving. */ * Merge delayed props back in with initial props, in case * we're DEBUG and zfs_ioc_recv_inject_err is set (which means * we have to make sure clear_received_props() includes * the delayed properties). * Since zfs_ioc_recv_inject_err is only in DEBUG kernels, * using ASSERT() will be just like a VERIFY. * Now that all props, initial and delayed, are set, report the prop * Caller made zc->zc_nvlist_dst less than the minimum expected * size or supplied an invalid address. * On error, restore the original props. * We failed to clear the received properties. * Since we may have left a $recvd value on the * system, we can't clear the $hasrecvd flag. /* We failed to stash the original properties. */ * dsl_props_set() will not convert RECEIVED to LOCAL on or * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL * explictly if we're restoring local properties cleared in the * first new-style receive. * We stashed the original properties but failed to * zc_name name of snapshot to send * zc_cookie file descriptor to send stream to * zc_obj fromorigin flag (mutually exclusive with zc_fromobj) * zc_sendobj objsetid of snapshot to send * zc_fromobj objsetid of incremental fromsnap (may be zero) * zc_guid if set, estimate size of stream only. zc_cookie is ignored. * output size in zc_objset_type. * zc_flags lzc_send_flags * zc_objset_type estimated size, if zc_guid is set * zc_name name of snapshot on which to report progress * zc_cookie file descriptor of send stream * zc_cookie number of bytes written in send stream thus far * Iterate over all the send streams currently active on this dataset. * If there's one which matches the specified file descriptor _and_ the * stream was started by the current process, return the progress of * On zpool clear we also fix up missing slogs * Resume any suspended I/Os. * If a resilver is already in progress then set the * spa_scrub_reopen flag to B_TRUE so that we don't restart * the scan as a side effect of the reopen. Otherwise, let * vdev_open() decided if a resilver is required. * zc_name name of filesystem * zc_value name of origin snapshot * zc_string name of conflicting snapshot, if there is one * We don't need to unmount *all* the origin fs's snapshots, but * Retrieve a single {user|group}{used|quota}@... property. * zc_name name of filesystem * zc_objset_type zfs_userquota_prop_t * zc_value domain name (eg. "S-1-234-567-89") * zc_cookie property value * zc_name name of filesystem * zc_objset_type zfs_userquota_prop_t * zc_nvlist_dst[_size] buffer to fill (not really an nvlist) * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t) * zc_name name of filesystem * If userused is not enabled, it may be because the * objset needs to be closed & reopened (to grow the /* XXX kind of reading contents without owning */ * We don't want to have a hard dependency * against some special symbols in sharefs * nfs, and smbsrv. Determine them if needed when * the first file system is shared. * Neither sharefs, nfs or smbsrv are unloadable modules. /* Both NFS and SMB shares also require sharetab support. */ * Add or remove share from sharetab * zc_name name of containing filesystem * zc_obj object # beyond which we want next in-use object # * zc_obj next in-use object # * zc_name name of filesystem * zc_value prefix name for snapshot * zc_cleanup_fd cleanup-on-exit file descriptor for calling process * zc_value short name of new snapshot * zc_name name of "to" snapshot * zc_value name of "from" snapshot * zc_cookie file descriptor to write diff data on * dmu_diff_record_t's to the file descriptor * Remove all ACL files in shares dir /* Now make sure mntpnt and dataset are ZFS */ * Create share dir if its missing. * "holds" -> { snapname -> holdname (string), ... } * (optional) "cleanup_fd" -> fd (int32) * snapname -> error value (int32) /* make sure the user didn't pass us any invalid (empty) tags */ * holdname -> time added (uint64 seconds since epoch) * snapname -> { holdname, ... } * snapname -> error value (int32) * zc_name name of new filesystem or snapshot * zc_value full name of old snapshot * zc_cookie space in bytes * zc_objset_type compressed space in bytes * zc_perm_action uncompressed space in bytes * "firstsnap" -> snapshot name * "used" -> space in bytes * "compressed" -> compressed space in bytes * "uncompressed" -> uncompressed space in bytes * "fd" -> file descriptor to write stream to (int32) * (optional) "fromsnap" -> full snap name to send an incremental from * (optional) "largeblockok" -> (value ignored) * indicates that blocks > 128KB are permitted * (optional) "embedok" -> (value ignored) * presence indicates DRR_WRITE_EMBEDDED records are permitted * (optional) "resume_object" and "resume_offset" -> (uint64) * if present, resume send stream from specified object and offset. * 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(). * (optional) "from" -> full snap or bookmark name to send an incremental * "space" -> bytes of space (uint64) * If from is a snapshot, hold it and use the more * efficient dmu_send_estimate to estimate send space * 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. * from is not properly formatted as a snapshot or // If estimating the size of a full send, use dmu_send_estimate * See the block comment at the beginning of this file for details on * each argument to this function. /* if we are logging, the name must be valid */ /* IOCTLS that use the legacy function signature */ * pool destroy, and export don't log the history as part of * zfsdev_ioctl, but rather zfs_ioc_pool_export * does the logging of those commands. * Find a free minor number. /* This is the control device. Allocate a new minor if requested. */ * Ensure that all pool/dataset names are valid before we pass down to /* legacy ioctls can modify zc_name */ * Add the innvl to the lognv before calling the func, * in case the func changes the innvl. * OK, so this is a little weird. * /dev/zfs is the control node, i.e. minor 0. * /dev/zfs has basically nothing to do except serve up ioctls, * so most of the standard driver entry points are in zvol.c. NULL,
/* no bus operations */