4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
26 #include <sys/zfs_ioctl.h>
27 #include <zfs_ioctl_compat.h>
28 #include "libzfs_core_compat.h"
30 extern int zfs_ioctl_version;
33 lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
36 nvpair_t *pair, *hpair;
44 if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
51 type32 = fnvlist_lookup_int32(*source, "type");
52 zc->zc_objset_type = (uint64_t)type32;
53 nvlist_lookup_nvlist(*source, "props", &nvl);
57 buf = fnvlist_lookup_string(*source, "origin");
58 strlcpy(zc->zc_value, buf, MAXPATHLEN);
59 nvlist_lookup_nvlist(*source, "props", &nvl);
60 *ioc = ZFS_IOC_CREATE;
63 case ZFS_IOC_SNAPSHOT:
64 nvl = fnvlist_lookup_nvlist(*source, "snaps");
65 pair = nvlist_next_nvpair(nvl, NULL);
67 buf = nvpair_name(pair);
68 pos = strcspn(buf, "@");
69 strlcpy(zc->zc_name, buf, pos + 1);
70 strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
73 /* old kernel cannot create multiple snapshots */
74 if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
78 nvlist_lookup_nvlist(*source, "props", &nvl);
81 case ZFS_IOC_SPACE_SNAPS:
82 buf = fnvlist_lookup_string(*source, "firstsnap");
83 strlcpy(zc->zc_value, buf, MAXPATHLEN);
85 case ZFS_IOC_DESTROY_SNAPS:
86 nvl = fnvlist_lookup_nvlist(*source, "snaps");
87 pair = nvlist_next_nvpair(nvl, NULL);
89 buf = nvpair_name(pair);
90 pos = strcspn(buf, "@");
91 strlcpy(zc->zc_name, buf, pos + 1);
94 /* old kernel cannot atomically destroy multiple snaps */
95 if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
100 nvl = fnvlist_lookup_nvlist(*source, "holds");
101 pair = nvlist_next_nvpair(nvl, NULL);
103 buf = nvpair_name(pair);
104 pos = strcspn(buf, "@");
105 strlcpy(zc->zc_name, buf, pos + 1);
106 strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
107 if (nvpair_value_string(pair, &val) == 0)
108 strlcpy(zc->zc_string, val, MAXNAMELEN);
113 /* old kernel cannot atomically create multiple holds */
114 if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
117 if (nvlist_lookup_int32(*source, "cleanup_fd",
119 zc->zc_cleanup_fd = cleanup_fd;
121 zc->zc_cleanup_fd = -1;
123 case ZFS_IOC_RELEASE:
124 pair = nvlist_next_nvpair(*source, NULL);
126 buf = nvpair_name(pair);
127 pos = strcspn(buf, "@");
128 strlcpy(zc->zc_name, buf, pos + 1);
129 strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
130 if (nvpair_value_nvlist(pair, &nvl) == 0) {
131 hpair = nvlist_next_nvpair(nvl, NULL);
133 strlcpy(zc->zc_string,
134 nvpair_name(hpair), MAXNAMELEN);
137 if (!error && nvlist_next_nvpair(nvl,
144 /* old kernel cannot atomically release multiple holds */
145 if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
154 lzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
156 if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
162 case ZFS_IOC_SNAPSHOT:
163 case ZFS_IOC_SPACE_SNAPS:
164 case ZFS_IOC_DESTROY_SNAPS:
165 zc->zc_nvlist_dst_filled = B_FALSE;
171 lzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
175 if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
179 case ZFS_IOC_SPACE_SNAPS:
180 nvl = fnvlist_alloc();
181 fnvlist_add_uint64(nvl, "used", zc->zc_cookie);
182 fnvlist_add_uint64(nvl, "compressed", zc->zc_objset_type);
183 fnvlist_add_uint64(nvl, "uncompressed", zc->zc_perm_action);