libzfs_core_compat.c revision 248461
1248435Smm/*
2248435Smm * CDDL HEADER START
3248435Smm *
4248435Smm * The contents of this file are subject to the terms of the
5248435Smm * Common Development and Distribution License (the "License").
6248435Smm * You may not use this file except in compliance with the License.
7248435Smm *
8248435Smm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9248435Smm * or http://www.opensolaris.org/os/licensing.
10248435Smm * See the License for the specific language governing permissions
11248435Smm * and limitations under the License.
12248435Smm *
13248435Smm * When distributing Covered Code, include this CDDL HEADER in each
14248435Smm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15248435Smm * If applicable, add the following below this CDDL HEADER, with the
16248435Smm * fields enclosed by brackets "[]" replaced with your own identifying
17248435Smm * information: Portions Copyright [yyyy] [name of copyright owner]
18248435Smm *
19248435Smm * CDDL HEADER END
20248435Smm */
21248435Smm
22248435Smm/*
23248435Smm * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
24248435Smm */
25248435Smm
26248435Smm#include <sys/zfs_ioctl.h>
27248445Smm#include <zfs_ioctl_compat.h>
28248445Smm#include "libzfs_core_compat.h"
29248435Smm
30248461Smmextern int zfs_ioctl_version;
31248435Smm
32248435Smmint
33248435Smmlzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
34248435Smm{
35248435Smm	nvlist_t *nvl = NULL;
36248435Smm	nvpair_t *pair;
37248435Smm	char *buf;
38248435Smm	zfs_ioc_t vecnum;
39248435Smm	uint32_t type32;
40248435Smm	int error = 0;
41248435Smm	int pos;
42248435Smm
43248461Smm	if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
44248435Smm		return (0);
45248435Smm
46248435Smm	vecnum = *ioc;
47248435Smm
48248435Smm	switch (vecnum) {
49248435Smm	case ZFS_IOC_CREATE:
50248435Smm		type32 = fnvlist_lookup_int32(*source, "type");
51248435Smm		zc->zc_objset_type = (uint64_t)type32;
52248435Smm		nvlist_lookup_nvlist(*source, "props", &nvl);
53248435Smm		*source = nvl;
54248435Smm	break;
55248435Smm	case ZFS_IOC_CLONE:
56248435Smm		buf = fnvlist_lookup_string(*source, "origin");
57248435Smm		strlcpy(zc->zc_value, buf, MAXPATHLEN);
58248435Smm		nvlist_lookup_nvlist(*source, "props", &nvl);
59248435Smm		*ioc = ZFS_IOC_CREATE;
60248435Smm		*source = nvl;
61248435Smm	break;
62248435Smm	case ZFS_IOC_SNAPSHOT:
63248435Smm		nvl = fnvlist_lookup_nvlist(*source, "snaps");
64248435Smm		pair = nvlist_next_nvpair(nvl, NULL);
65248435Smm		if (pair != NULL) {
66248435Smm			buf = nvpair_name(pair);
67248435Smm			pos = strcspn(buf, "@");
68248435Smm			strlcpy(zc->zc_name, buf, pos + 1);
69248435Smm			strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
70248435Smm		} else
71248435Smm			error = EOPNOTSUPP;
72248435Smm		/* old kernel cannot create multiple snapshots */
73248435Smm		if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
74248435Smm			error = EOPNOTSUPP;
75248435Smm		nvlist_free(nvl);
76248435Smm		nvl = NULL;
77248435Smm		nvlist_lookup_nvlist(*source, "props", &nvl);
78248435Smm		*source = nvl;
79248435Smm	break;
80248435Smm	case ZFS_IOC_SPACE_SNAPS:
81248435Smm		buf = fnvlist_lookup_string(*source, "firstsnap");
82248435Smm		strlcpy(zc->zc_value, buf, MAXPATHLEN);
83248435Smm	break;
84248435Smm	case ZFS_IOC_DESTROY_SNAPS:
85248435Smm		nvl = fnvlist_lookup_nvlist(*source, "snaps");
86248435Smm		pair = nvlist_next_nvpair(nvl, NULL);
87248435Smm		if (pair != NULL) {
88248435Smm			buf = nvpair_name(pair);
89248435Smm			pos = strcspn(buf, "@");
90248435Smm			strlcpy(zc->zc_name, buf, pos + 1);
91248435Smm		}
92248435Smm		*source = nvl;
93248435Smm	break;
94248435Smm	}
95248435Smm
96248435Smm	return (error);
97248435Smm}
98248435Smm
99248435Smmvoid
100248435Smmlzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
101248435Smm{
102248461Smm	if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
103248435Smm		return;
104248435Smm
105248435Smm	switch (ioc) {
106248435Smm	case ZFS_IOC_CREATE:
107248435Smm	case ZFS_IOC_CLONE:
108248435Smm	case ZFS_IOC_SNAPSHOT:
109248435Smm	case ZFS_IOC_SPACE_SNAPS:
110248435Smm	case ZFS_IOC_DESTROY_SNAPS:
111248435Smm		zc->zc_nvlist_dst_filled = B_FALSE;
112248435Smm	break;
113248435Smm	}
114248435Smm}
115248435Smm
116248435Smmint
117248435Smmlzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
118248435Smm{
119248435Smm	nvlist_t *nvl;
120248435Smm
121248461Smm	if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
122248435Smm		return (0);
123248435Smm
124248435Smm	switch (ioc) {
125248435Smm	case ZFS_IOC_SPACE_SNAPS:
126248435Smm		nvl = fnvlist_alloc();
127248435Smm		fnvlist_add_uint64(nvl, "used", zc->zc_cookie);
128248435Smm		fnvlist_add_uint64(nvl, "compressed", zc->zc_objset_type);
129248435Smm		fnvlist_add_uint64(nvl, "uncompressed", zc->zc_perm_action);
130248435Smm		*outnvl = nvl;
131248435Smm	break;
132248435Smm	}
133248435Smm
134248435Smm	return (0);
135248435Smm}
136