summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/common
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-03-19 12:51:18 +0000
committermm <mm@FreeBSD.org>2013-03-19 12:51:18 +0000
commit7c87858955593be19a80e57b7353b09f5587ae9b (patch)
tree68fb8eac18f4259926de9bd4d4ecba5b46b638c3 /sys/cddl/contrib/opensolaris/common
parentc94cc27299ba2ab2acf00ca31ec90c92a37b16f7 (diff)
parent09a831de87c71a9f94f38dbd36b73746467e3182 (diff)
downloadFreeBSD-src-7c87858955593be19a80e57b7353b09f5587ae9b.zip
FreeBSD-src-7c87858955593be19a80e57b7353b09f5587ae9b.tar.gz
MFV r247580:
Merge synctask code restructuring from vendor. Modify forward and backward compatibility to support new change. Illumos ZFS issues: 3464 zfs synctask code needs restructuring Sponsored by: Hybrid Logic Ltd.
Diffstat (limited to 'sys/cddl/contrib/opensolaris/common')
-rw-r--r--sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c14
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c92
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h2
3 files changed, 98 insertions, 10 deletions
diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c
index 1b67e62..eb200a2 100644
--- a/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c
+++ b/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c
@@ -30,6 +30,8 @@
#else
#include <sys/debug.h>
#include <sys/kmem.h>
+#include <sys/param.h>
+#include <sys/debug.h>
#endif
/*
@@ -116,6 +118,18 @@ fnvlist_merge(nvlist_t *dst, nvlist_t *src)
VERIFY0(nvlist_merge(dst, src, KM_SLEEP));
}
+size_t
+fnvlist_num_pairs(nvlist_t *nvl)
+{
+ size_t count = 0;
+ nvpair_t *pair;
+
+ for (pair = nvlist_next_nvpair(nvl, 0); pair != NULL;
+ pair = nvlist_next_nvpair(nvl, pair))
+ count++;
+ return (count);
+}
+
void
fnvlist_add_boolean(nvlist_t *nvl, const char *name)
{
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
index f0318b0..df91b2e 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
@@ -59,7 +59,6 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN);
strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2);
strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN);
- strlcpy(zc->zc_top_ds, zcdm_c->zc_top_ds, MAXPATHLEN);
zc->zc_guid = zcdm_c->zc_guid;
zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf;
zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size;
@@ -104,7 +103,6 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
- strlcpy(zc->zc_top_ds, zc28_c->zc_top_ds, MAXPATHLEN);
zc->zc_guid = zc28_c->zc_guid;
zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
@@ -220,7 +218,8 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
}
void
-zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
+zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
+ const int cflag)
{
zfs_cmd_v15_t *zc_c;
zfs_cmd_v28_t *zc28_c;
@@ -233,7 +232,6 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN);
strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN);
- strlcpy(zcdm_c->zc_top_ds, zc->zc_top_ds, MAXPATHLEN);
zcdm_c->zc_guid = zc->zc_guid;
zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf;
zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
@@ -266,7 +264,12 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
/* zc_inject_record doesn't change in libzfs_core */
zc->zc_inject_record = zcdm_c->zc_inject_record;
-
+#ifndef _KERNEL
+ if (request == ZFS_IOC_RECV)
+ strlcpy(zcdm_c->zc_top_ds,
+ zc->zc_value + strlen(zc->zc_value) + 1,
+ (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1);
+#endif
break;
case ZFS_CMD_COMPAT_V28:
@@ -275,7 +278,6 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
- strlcpy(zc28_c->zc_top_ds, zc->zc_top_ds, MAXPATHLEN);
zc28_c->zc_guid = zc->zc_guid;
zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
@@ -305,7 +307,12 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
zc28_c->zc_fromobj = zc->zc_fromobj;
zc28_c->zc_createtxg = zc->zc_createtxg;
zc28_c->zc_stat = zc->zc_stat;
-
+#ifndef _KERNEL
+ if (request == ZFS_IOC_RECV)
+ strlcpy(zc28_c->zc_top_ds,
+ zc->zc_value + strlen(zc->zc_value) + 1,
+ MAXPATHLEN * 2 - strlen(zc->zc_value) - 1);
+#endif
/* zc_inject_record */
zc28_c->zc_inject_record.zi_objset =
zc->zc_inject_record.zi_objset;
@@ -596,7 +603,8 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
return (ENOTSUP);
- zfs_cmd_compat_put(zc, (caddr_t)zc_c, cflag);
+ zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
+
ret = ioctl(fd, ncmd, zc_c);
if (cflag == ZFS_CMD_COMPAT_V15 &&
nc == ZFS_IOC_POOL_IMPORT)
@@ -664,7 +672,8 @@ nvlist_t *
zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
const int cflag)
{
- nvlist_t *nvl, *tmpnvl;
+ nvlist_t *nvl, *tmpnvl, *hnvl;
+ nvpair_t *elem;
char *poolname, *snapname;
int err;
@@ -745,6 +754,69 @@ zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
return (nvl);
break;
+ case ZFS_IOC_HOLD:
+ nvl = fnvlist_alloc();
+ tmpnvl = fnvlist_alloc();
+ if (zc->zc_cleanup_fd != -1)
+ fnvlist_add_int32(nvl, "cleanup_fd",
+ (int32_t)zc->zc_cleanup_fd);
+ if (zc->zc_cookie) {
+ hnvl = fnvlist_alloc();
+ if (dmu_get_recursive_snaps_nvl(zc->zc_name,
+ zc->zc_value, hnvl) == 0) {
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(hnvl,
+ elem)) != NULL) {
+ nvlist_add_string(tmpnvl,
+ nvpair_name(elem), zc->zc_string);
+ }
+ }
+ nvlist_free(hnvl);
+ } else {
+ snapname = kmem_asprintf("%s@%s", zc->zc_name,
+ zc->zc_value);
+ nvlist_add_string(tmpnvl, snapname, zc->zc_string);
+ kmem_free(snapname, strlen(snapname + 1));
+ }
+ fnvlist_add_nvlist(nvl, "holds", tmpnvl);
+ nvlist_free(tmpnvl);
+ if (innvl != NULL)
+ nvlist_free(innvl);
+ /* strip dataset part from zc->zc_name */
+ zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
+ return (nvl);
+ break;
+ case ZFS_IOC_RELEASE:
+ nvl = fnvlist_alloc();
+ tmpnvl = fnvlist_alloc();
+ if (zc->zc_cookie) {
+ hnvl = fnvlist_alloc();
+ if (dmu_get_recursive_snaps_nvl(zc->zc_name,
+ zc->zc_value, hnvl) == 0) {
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(hnvl,
+ elem)) != NULL) {
+ fnvlist_add_boolean(tmpnvl,
+ zc->zc_string);
+ fnvlist_add_nvlist(nvl,
+ nvpair_name(elem), tmpnvl);
+ }
+ }
+ nvlist_free(hnvl);
+ } else {
+ snapname = kmem_asprintf("%s@%s", zc->zc_name,
+ zc->zc_value);
+ fnvlist_add_boolean(tmpnvl, zc->zc_string);
+ fnvlist_add_nvlist(nvl, snapname, tmpnvl);
+ kmem_free(snapname, strlen(snapname + 1));
+ }
+ nvlist_free(tmpnvl);
+ if (innvl != NULL)
+ nvlist_free(innvl);
+ /* strip dataset part from zc->zc_name */
+ zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
+ return (nvl);
+ break;
}
out:
return (innvl);
@@ -773,6 +845,8 @@ zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
break;
case ZFS_IOC_CREATE:
case ZFS_IOC_CLONE:
+ case ZFS_IOC_HOLD:
+ case ZFS_IOC_RELEASE:
nvlist_free(outnvl);
/* return empty outnvl */
tmpnvl = fnvlist_alloc();
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
index 57c2909..0e7130d 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
@@ -326,7 +326,7 @@ nvlist_t *zfs_ioctl_compat_outnvl(zfs_cmd_t *, nvlist_t *, const int,
int zcmd_ioctl_compat(int, int, zfs_cmd_t *, const int);
#endif /* _KERNEL */
void zfs_cmd_compat_get(zfs_cmd_t *, caddr_t, const int);
-void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int);
+void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int, const int);
#ifdef __cplusplus
}
OpenPOWER on IntegriCloud