diff options
Diffstat (limited to 'sys/cddl')
96 files changed, 1940 insertions, 848 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index a2532f8..49becbc 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -196,6 +196,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, VI_UNLOCK(vp); vrele(vp); vfs_unbusy(mp); + vfs_freeopts(mp->mnt_optnew); vfs_mount_destroy(mp); *vpp = NULL; return (error); diff --git a/sys/cddl/compat/opensolaris/sys/callo.h b/sys/cddl/compat/opensolaris/sys/callo.h new file mode 100644 index 0000000..df2ae69 --- /dev/null +++ b/sys/cddl/compat/opensolaris/sys/callo.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2016 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_CALLO_H_ +#define _OPENSOLARIS_SYS_CALLO_H_ + +#include_next <sys/callout.h> + +#define CALLOUT_REALTIME 0 /* realtime callout type */ +#define CALLOUT_NORMAL 1 /* normal callout type */ + +#endif /* !_OPENSOLARIS_SYS_CALLO_H_ */ diff --git a/sys/cddl/compat/opensolaris/sys/systm.h b/sys/cddl/compat/opensolaris/sys/systm.h index fe0e199..f6a0dce 100644 --- a/sys/cddl/compat/opensolaris/sys/systm.h +++ b/sys/cddl/compat/opensolaris/sys/systm.h @@ -42,6 +42,9 @@ #define delay(x) pause("soldelay", (x)) +#define timeout_generic(type, fn, arg, t, r, f) \ + timeout(fn, arg, t / (NANOSEC/hz) + 1) + #endif /* _KERNEL */ #endif /* _OPENSOLARIS_SYS_SYSTM_H_ */ diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h index fe4857a..269424f 100644 --- a/sys/cddl/compat/opensolaris/sys/time.h +++ b/sys/cddl/compat/opensolaris/sys/time.h @@ -40,6 +40,9 @@ #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) +#define NSEC2SEC(n) ((n) / (NANOSEC / SEC)) +#define SEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / SEC)) + typedef longlong_t hrtime_t; #if defined(__i386__) || defined(__powerpc__) diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c index 7038f7f..4bba05a 100644 --- a/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c +++ b/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c @@ -544,8 +544,7 @@ nvpair_free(nvpair_t *nvp) int i; for (i = 0; i < NVP_NELEM(nvp); i++) - if (nvlp[i] != NULL) - nvlist_free(nvlp[i]); + nvlist_free(nvlp[i]); break; } default: diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c index 6eade2a..57e5f5e 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c @@ -24,6 +24,7 @@ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifdef _KERNEL diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h index 56f3da7..eea60f3 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h @@ -23,6 +23,7 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _ZFEATURE_COMMON_H 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 39ad7ce..0d8971c 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c @@ -54,8 +54,69 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) zfs_cmd_deadman_t *zcdm_c; zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; + zfs_cmd_resume_t *resume_c; switch (cflag) { + case ZFS_CMD_COMPAT_RESUME: + resume_c = (void *)addr; + /* zc */ + strlcpy(zc->zc_name, resume_c->zc_name, MAXPATHLEN); + strlcpy(zc->zc_value, resume_c->zc_value, MAXPATHLEN * 2); + strlcpy(zc->zc_string, resume_c->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) zc->field = resume_c->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(zc->zc_inject_record.zi_func, + resume_c->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + zc->zc_inject_record.zi_nlanes = 1; + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_resumable); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_EDBP: edbp_c = (void *)addr; /* zc */ @@ -63,40 +124,57 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2); strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN); -#define ZCMD_COPY(field) zc->field = edbp_c->field - ZCMD_COPY(zc_nvlist_src); - ZCMD_COPY(zc_nvlist_src_size); - ZCMD_COPY(zc_nvlist_dst); - ZCMD_COPY(zc_nvlist_dst_size); - ZCMD_COPY(zc_nvlist_dst_filled); - ZCMD_COPY(zc_pad2); - ZCMD_COPY(zc_history); - ZCMD_COPY(zc_guid); - ZCMD_COPY(zc_nvlist_conf); - ZCMD_COPY(zc_nvlist_conf_size); - ZCMD_COPY(zc_cookie); - ZCMD_COPY(zc_objset_type); - ZCMD_COPY(zc_perm_action); - ZCMD_COPY(zc_history_len); - ZCMD_COPY(zc_history_offset); - ZCMD_COPY(zc_obj); - ZCMD_COPY(zc_iflags); - ZCMD_COPY(zc_share); - ZCMD_COPY(zc_jailid); - ZCMD_COPY(zc_objset_stats); +#define FIELD_COPY(field) zc->field = edbp_c->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record; - ZCMD_COPY(zc_inject_record); - ZCMD_COPY(zc_defer_destroy); - ZCMD_COPY(zc_flags); - ZCMD_COPY(zc_action_handle); - ZCMD_COPY(zc_cleanup_fd); - ZCMD_COPY(zc_simple); + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(zc->zc_inject_record.zi_func, + edbp_c->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + zc->zc_inject_record.zi_nlanes = 1; + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); zc->zc_resumable = B_FALSE; - ZCMD_COPY(zc_sendobj); - ZCMD_COPY(zc_fromobj); - ZCMD_COPY(zc_createtxg); - ZCMD_COPY(zc_stat); -#undef ZCMD_COPY + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY break; case ZFS_CMD_COMPAT_ZCMD: @@ -106,43 +184,60 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2); strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN); -#define ZCMD_COPY(field) zc->field = zcmd_c->field - ZCMD_COPY(zc_nvlist_src); - ZCMD_COPY(zc_nvlist_src_size); - ZCMD_COPY(zc_nvlist_dst); - ZCMD_COPY(zc_nvlist_dst_size); - ZCMD_COPY(zc_nvlist_dst_filled); - ZCMD_COPY(zc_pad2); - ZCMD_COPY(zc_history); - ZCMD_COPY(zc_guid); - ZCMD_COPY(zc_nvlist_conf); - ZCMD_COPY(zc_nvlist_conf_size); - ZCMD_COPY(zc_cookie); - ZCMD_COPY(zc_objset_type); - ZCMD_COPY(zc_perm_action); - ZCMD_COPY(zc_history_len); - ZCMD_COPY(zc_history_offset); - ZCMD_COPY(zc_obj); - ZCMD_COPY(zc_iflags); - ZCMD_COPY(zc_share); - ZCMD_COPY(zc_jailid); - ZCMD_COPY(zc_objset_stats); +#define FIELD_COPY(field) zc->field = zcmd_c->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record; - ZCMD_COPY(zc_inject_record); + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(zc->zc_inject_record.zi_func, + zcmd_c->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + zc->zc_inject_record.zi_nlanes = 1; + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); /* boolean_t -> uint32_t */ zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy); zc->zc_flags = 0; - ZCMD_COPY(zc_action_handle); - ZCMD_COPY(zc_cleanup_fd); - ZCMD_COPY(zc_simple); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); zc->zc_resumable = B_FALSE; - ZCMD_COPY(zc_sendobj); - ZCMD_COPY(zc_fromobj); - ZCMD_COPY(zc_createtxg); - ZCMD_COPY(zc_stat); -#undef ZCMD_COPY + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY break; @@ -152,6 +247,8 @@ 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); + +#define FIELD_COPY(field) zc->field = zcdm_c->field 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; @@ -181,12 +278,28 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) zc->zc_fromobj = zcdm_c->zc_fromobj; zc->zc_createtxg = zcdm_c->zc_createtxg; zc->zc_stat = zcdm_c->zc_stat; - - /* zc_inject_record doesn't change in libzfs_core */ - zcdm_c->zc_inject_record = zc->zc_inject_record; + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(zc->zc_inject_record.zi_func, + resume_c->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + zc->zc_inject_record.zi_nlanes = 1; + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); /* we always assume zc_nvlist_dst_filled is true */ zc->zc_nvlist_dst_filled = B_TRUE; +#undef FIELD_COPY break; case ZFS_CMD_COMPAT_V28: @@ -255,6 +368,7 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) zc28_c->zc_inject_record.zi_duration; zc->zc_inject_record.zi_timer = zc28_c->zc_inject_record.zi_timer; + zc->zc_inject_record.zi_nlanes = 1; zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED; zc->zc_inject_record.zi_pad = 0; break; @@ -319,47 +433,121 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, zfs_cmd_deadman_t *zcdm_c; zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; + zfs_cmd_resume_t *resume_c; switch (cflag) { + case ZFS_CMD_COMPAT_RESUME: + resume_c = (void *)addr; + strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN); + strlcpy(resume_c->zc_value, zc->zc_value, MAXPATHLEN * 2); + strlcpy(resume_c->zc_string, zc->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) resume_c->field = zc->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(resume_c->zc_inject_record.zi_func, + zc->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_EDBP: edbp_c = (void *)addr; strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN); strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2); strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN); -#define ZCMD_COPY(field) edbp_c->field = zc->field - ZCMD_COPY(zc_nvlist_src); - ZCMD_COPY(zc_nvlist_src_size); - ZCMD_COPY(zc_nvlist_dst); - ZCMD_COPY(zc_nvlist_dst_size); - ZCMD_COPY(zc_nvlist_dst_filled); - ZCMD_COPY(zc_pad2); - ZCMD_COPY(zc_history); - ZCMD_COPY(zc_guid); - ZCMD_COPY(zc_nvlist_conf); - ZCMD_COPY(zc_nvlist_conf_size); - ZCMD_COPY(zc_cookie); - ZCMD_COPY(zc_objset_type); - ZCMD_COPY(zc_perm_action); - ZCMD_COPY(zc_history_len); - ZCMD_COPY(zc_history_offset); - ZCMD_COPY(zc_obj); - ZCMD_COPY(zc_iflags); - ZCMD_COPY(zc_share); - ZCMD_COPY(zc_jailid); - ZCMD_COPY(zc_objset_stats); +#define FIELD_COPY(field) edbp_c->field = zc->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; - ZCMD_COPY(zc_inject_record); - ZCMD_COPY(zc_defer_destroy); - ZCMD_COPY(zc_flags); - ZCMD_COPY(zc_action_handle); - ZCMD_COPY(zc_cleanup_fd); - ZCMD_COPY(zc_simple); - ZCMD_COPY(zc_sendobj); - ZCMD_COPY(zc_fromobj); - ZCMD_COPY(zc_createtxg); - ZCMD_COPY(zc_stat); -#undef ZCMD_COPY + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(resume_c->zc_inject_record.zi_func, + zc->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY break; case ZFS_CMD_COMPAT_ZCMD: @@ -369,42 +557,58 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2); strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN); -#define ZCMD_COPY(field) zcmd_c->field = zc->field - ZCMD_COPY(zc_nvlist_src); - ZCMD_COPY(zc_nvlist_src_size); - ZCMD_COPY(zc_nvlist_dst); - ZCMD_COPY(zc_nvlist_dst_size); - ZCMD_COPY(zc_nvlist_dst_filled); - ZCMD_COPY(zc_pad2); - ZCMD_COPY(zc_history); - ZCMD_COPY(zc_guid); - ZCMD_COPY(zc_nvlist_conf); - ZCMD_COPY(zc_nvlist_conf_size); - ZCMD_COPY(zc_cookie); - ZCMD_COPY(zc_objset_type); - ZCMD_COPY(zc_perm_action); - ZCMD_COPY(zc_history_len); - ZCMD_COPY(zc_history_offset); - ZCMD_COPY(zc_obj); - ZCMD_COPY(zc_iflags); - ZCMD_COPY(zc_share); - ZCMD_COPY(zc_jailid); - ZCMD_COPY(zc_objset_stats); +#define FIELD_COPY(field) zcmd_c->field = zc->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; - ZCMD_COPY(zc_inject_record); + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(resume_c->zc_inject_record.zi_func, + zc->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); /* boolean_t -> uint32_t */ zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy); zcmd_c->zc_temphold = 0; - ZCMD_COPY(zc_action_handle); - ZCMD_COPY(zc_cleanup_fd); - ZCMD_COPY(zc_simple); - ZCMD_COPY(zc_sendobj); - ZCMD_COPY(zc_fromobj); - ZCMD_COPY(zc_createtxg); - ZCMD_COPY(zc_stat); -#undef ZCMD_COPY + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY break; @@ -414,6 +618,8 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, 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); + +#define FIELD_COPY(field) zcdm_c->field = zc->field 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; @@ -442,9 +648,24 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, zcdm_c->zc_fromobj = zc->zc_fromobj; zcdm_c->zc_createtxg = zc->zc_createtxg; zcdm_c->zc_stat = zc->zc_stat; - - /* zc_inject_record doesn't change in libzfs_core */ - zc->zc_inject_record = zcdm_c->zc_inject_record; + FIELD_COPY(zc_inject_record.zi_objset); + FIELD_COPY(zc_inject_record.zi_object); + FIELD_COPY(zc_inject_record.zi_start); + FIELD_COPY(zc_inject_record.zi_end); + FIELD_COPY(zc_inject_record.zi_guid); + FIELD_COPY(zc_inject_record.zi_level); + FIELD_COPY(zc_inject_record.zi_error); + FIELD_COPY(zc_inject_record.zi_type); + FIELD_COPY(zc_inject_record.zi_freq); + FIELD_COPY(zc_inject_record.zi_failfast); + strlcpy(resume_c->zc_inject_record.zi_func, + zc->zc_inject_record.zi_func, MAXNAMELEN); + FIELD_COPY(zc_inject_record.zi_iotype); + FIELD_COPY(zc_inject_record.zi_duration); + FIELD_COPY(zc_inject_record.zi_timer); + FIELD_COPY(zc_inject_record.zi_cmd); + FIELD_COPY(zc_inject_record.zi_pad); +#undef FIELD_COPY #ifndef _KERNEL if (request == ZFS_IOC_RECV) strlcpy(zcdm_c->zc_top_ds, @@ -766,6 +987,12 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) zp.zfs_cmd_size = sizeof(zfs_cmd_t); zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT; return (ioctl(fd, ncmd, &zp)); + case ZFS_CMD_COMPAT_RESUME: + ncmd = _IOWR('Z', request, struct zfs_iocparm); + zp.zfs_cmd = (uint64_t)zc; + zp.zfs_cmd_size = sizeof(zfs_cmd_resume_t); + zp.zfs_ioctl_version = ZFS_IOCVER_RESUME; + return (ioctl(fd, ncmd, &zp)); case ZFS_CMD_COMPAT_EDBP: ncmd = _IOWR('Z', request, struct zfs_iocparm); zp.zfs_cmd = (uint64_t)zc; @@ -876,7 +1103,8 @@ zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec, int err; if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || - cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP) + cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || + cflag == ZFS_CMD_COMPAT_RESUME) goto out; switch (vec) { @@ -1028,7 +1256,8 @@ zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec, nvlist_t *tmpnvl; if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || - cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP) + cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || + cflag == ZFS_CMD_COMPAT_RESUME) return (outnvl); switch (vec) { 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 8361aa3..6f24380 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h @@ -53,7 +53,8 @@ extern "C" { #define ZFS_IOCVER_ZCMD 3 #define ZFS_IOCVER_EDBP 4 #define ZFS_IOCVER_RESUME 5 -#define ZFS_IOCVER_CURRENT ZFS_IOCVER_RESUME +#define ZFS_IOCVER_INLANES 6 +#define ZFS_IOCVER_CURRENT ZFS_IOCVER_INLANES /* compatibility conversion flag */ #define ZFS_CMD_COMPAT_NONE 0 @@ -63,6 +64,7 @@ extern "C" { #define ZFS_CMD_COMPAT_LZC 4 #define ZFS_CMD_COMPAT_ZCMD 5 #define ZFS_CMD_COMPAT_EDBP 6 +#define ZFS_CMD_COMPAT_RESUME 7 #define ZFS_IOC_COMPAT_PASS 254 #define ZFS_IOC_COMPAT_FAIL 255 @@ -167,6 +169,25 @@ typedef struct zfs_cmd_v28 { zfs_stat_t zc_stat; } zfs_cmd_v28_t; +typedef struct zinject_record_deadman { + uint64_t zi_objset; + uint64_t zi_object; + uint64_t zi_start; + uint64_t zi_end; + uint64_t zi_guid; + uint32_t zi_level; + uint32_t zi_error; + uint64_t zi_type; + uint32_t zi_freq; + uint32_t zi_failfast; + char zi_func[MAXNAMELEN]; + uint32_t zi_iotype; + int32_t zi_duration; + uint64_t zi_timer; + uint32_t zi_cmd; + uint32_t zi_pad; +} zinject_record_deadman_t; + typedef struct zfs_cmd_deadman { char zc_name[MAXPATHLEN]; char zc_value[MAXPATHLEN * 2]; @@ -192,7 +213,7 @@ typedef struct zfs_cmd_deadman { dmu_objset_stats_t zc_objset_stats; struct drr_begin zc_begin_record; /* zc_inject_record doesn't change in libzfs_core */ - zinject_record_t zc_inject_record; + zinject_record_deadman_t zc_inject_record; boolean_t zc_defer_destroy; boolean_t zc_temphold; uint64_t zc_action_handle; @@ -235,7 +256,7 @@ typedef struct zfs_cmd_zcmd { uint64_t zc_jailid; dmu_objset_stats_t zc_objset_stats; struct drr_begin zc_begin_record; - zinject_record_t zc_inject_record; + zinject_record_deadman_t zc_inject_record; boolean_t zc_defer_destroy; boolean_t zc_temphold; uint64_t zc_action_handle; @@ -278,7 +299,7 @@ typedef struct zfs_cmd_edbp { uint64_t zc_jailid; dmu_objset_stats_t zc_objset_stats; struct drr_begin zc_begin_record; - zinject_record_t zc_inject_record; + zinject_record_deadman_t zc_inject_record; uint32_t zc_defer_destroy; uint32_t zc_flags; uint64_t zc_action_handle; @@ -291,6 +312,49 @@ typedef struct zfs_cmd_edbp { zfs_stat_t zc_stat; } zfs_cmd_edbp_t; +typedef struct zfs_cmd_resume { + char zc_name[MAXPATHLEN]; /* name of pool or dataset */ + uint64_t zc_nvlist_src; /* really (char *) */ + uint64_t zc_nvlist_src_size; + uint64_t zc_nvlist_dst; /* really (char *) */ + uint64_t zc_nvlist_dst_size; + boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ + int zc_pad2; + + /* + * The following members are for legacy ioctls which haven't been + * converted to the new method. + */ + uint64_t zc_history; /* really (char *) */ + char zc_value[MAXPATHLEN * 2]; + char zc_string[MAXNAMELEN]; + uint64_t zc_guid; + uint64_t zc_nvlist_conf; /* really (char *) */ + uint64_t zc_nvlist_conf_size; + uint64_t zc_cookie; + uint64_t zc_objset_type; + uint64_t zc_perm_action; + uint64_t zc_history_len; + uint64_t zc_history_offset; + uint64_t zc_obj; + uint64_t zc_iflags; /* internal to zfs(7fs) */ + zfs_share_t zc_share; + uint64_t zc_jailid; + dmu_objset_stats_t zc_objset_stats; + dmu_replay_record_t zc_begin_record; + zinject_record_deadman_t zc_inject_record; + uint32_t zc_defer_destroy; + uint32_t zc_flags; + uint64_t zc_action_handle; + int zc_cleanup_fd; + uint8_t zc_simple; + boolean_t zc_resumable; + uint64_t zc_sendobj; + uint64_t zc_fromobj; + uint64_t zc_createtxg; + zfs_stat_t zc_stat; +} zfs_cmd_resume_t; + #ifdef _KERNEL unsigned static long zfs_ioctl_v15_to_v28[] = { 0, /* 0 ZFS_IOC_POOL_CREATE */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c index 20b54d8..c310a67b 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -23,6 +23,7 @@ * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c index 4d906b0..9c71744 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c @@ -22,6 +22,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zio.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index 1955984..9266ffc 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -67,42 +67,42 @@ * on capital-f functions. */ #include <sys/errno.h> -#if !defined(sun) +#ifndef illumos #include <sys/time.h> #endif #include <sys/stat.h> #include <sys/modctl.h> #include <sys/conf.h> #include <sys/systm.h> -#if defined(sun) +#ifdef illumos #include <sys/ddi.h> #include <sys/sunddi.h> #endif #include <sys/cpuvar.h> #include <sys/kmem.h> -#if defined(sun) +#ifdef illumos #include <sys/strsubr.h> #endif #include <sys/sysmacros.h> #include <sys/dtrace_impl.h> #include <sys/atomic.h> #include <sys/cmn_err.h> -#if defined(sun) +#ifdef illumos #include <sys/mutex_impl.h> #include <sys/rwlock_impl.h> #endif #include <sys/ctf_api.h> -#if defined(sun) +#ifdef illumos #include <sys/panic.h> #include <sys/priv_impl.h> #endif #include <sys/policy.h> -#if defined(sun) +#ifdef illumos #include <sys/cred_impl.h> #include <sys/procfs_isa.h> #endif #include <sys/taskq.h> -#if defined(sun) +#ifdef illumos #include <sys/mkdev.h> #include <sys/kdi.h> #endif @@ -112,7 +112,7 @@ #include "strtolctype.h" /* FreeBSD includes: */ -#if !defined(sun) +#ifndef illumos #include <sys/callout.h> #include <sys/ctype.h> #include <sys/eventhandler.h> @@ -184,7 +184,7 @@ hrtime_t dtrace_deadman_interval = NANOSEC; hrtime_t dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC; hrtime_t dtrace_deadman_user = (hrtime_t)30 * NANOSEC; hrtime_t dtrace_unregister_defunct_reap = (hrtime_t)60 * NANOSEC; -#if !defined(sun) +#ifndef illumos int dtrace_memstr_max = 4096; #endif @@ -202,10 +202,10 @@ const char dtrace_zero[256] = { 0 }; /* zero-filled memory */ /* * DTrace Internal Variables */ -#if defined(sun) +#ifdef illumos static dev_info_t *dtrace_devi; /* device info */ #endif -#if defined(sun) +#ifdef illumos static vmem_t *dtrace_arena; /* probe ID arena */ static vmem_t *dtrace_minor; /* minor number arena */ #else @@ -219,7 +219,7 @@ static dtrace_meta_t *dtrace_meta_pid; /* user-land meta provider */ static int dtrace_opens; /* number of opens */ static int dtrace_helpers; /* number of helpers */ static int dtrace_getf; /* number of unpriv getf()s */ -#if defined(sun) +#ifdef illumos static void *dtrace_softstate; /* softstate pointer */ #endif static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */ @@ -239,7 +239,7 @@ static dtrace_enabling_t *dtrace_retained; /* list of retained enablings */ static dtrace_genid_t dtrace_retained_gen; /* current retained enab gen */ static dtrace_dynvar_t dtrace_dynhash_sink; /* end of dynamic hash chains */ static int dtrace_dynvar_failclean; /* dynvars failed to clean */ -#if !defined(sun) +#ifndef illumos static struct mtx dtrace_unr_mtx; MTX_SYSINIT(dtrace_unr_mtx, &dtrace_unr_mtx, "Unique resource identifier", MTX_DEF); int dtrace_in_probe; /* non-zero if executing a probe */ @@ -284,7 +284,7 @@ static kmutex_t dtrace_lock; /* probe state lock */ static kmutex_t dtrace_provider_lock; /* provider state lock */ static kmutex_t dtrace_meta_lock; /* meta-provider state lock */ -#if !defined(sun) +#ifndef illumos /* XXX FreeBSD hacks. */ #define cr_suid cr_svuid #define cr_sgid cr_svgid @@ -309,7 +309,7 @@ SYSCTL_DECL(_debug_dtrace); SYSCTL_DECL(_kern_dtrace); #endif -#if defined(sun) +#ifdef illumos #define curcpu CPU->cpu_id #endif @@ -424,7 +424,7 @@ static kmutex_t dtrace_errlock; * no way for a global variable key signature to match a thread-local key * signature. */ -#if defined(sun) +#ifdef illumos #define DTRACE_TLS_THRKEY(where) { \ uint_t intr = 0; \ uint_t actv = CPU->cpu_intr_actv >> (LOCK_LEVEL + 1); \ @@ -857,7 +857,7 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate, return (1); } -#if defined(sun) +#ifdef illumos if (p != NULL && p->p_pidp != NULL && DTRACE_INRANGE(addr, sz, &(p->p_pidp->pid_id), sizeof (pid_t))) { return (1); @@ -891,7 +891,7 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate, return (1); if ((vp = fp->f_vnode) != NULL) { -#if defined(sun) +#ifdef illumos if (DTRACE_INRANGE(addr, sz, &vp->v_path, psz)) return (1); if (vp->v_path != NULL && DTRACE_INRANGE(addr, sz, @@ -903,7 +903,7 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate, if (DTRACE_INRANGE(addr, sz, &vp->v_op, psz)) return (1); -#if defined(sun) +#ifdef illumos if ((op = vp->v_op) != NULL && DTRACE_INRANGE(addr, sz, &op->vnop_name, psz)) { return (1); @@ -1340,7 +1340,7 @@ dtrace_priv_proc_common_user(dtrace_state_t *state) static int dtrace_priv_proc_common_zone(dtrace_state_t *state) { -#if defined(sun) +#ifdef illumos cred_t *cr, *s_cr = state->dts_cred.dcr_cred; /* @@ -1465,7 +1465,7 @@ dtrace_priv_probe(dtrace_state_t *state, dtrace_mstate_t *mstate, ASSERT(ecb->dte_cond); -#if defined(sun) +#ifdef illumos if (pops->dtps_mode != NULL) { mode = pops->dtps_mode(prov->dtpv_arg, probe->dtpr_id, probe->dtpr_arg); @@ -1524,13 +1524,13 @@ dtrace_priv_probe(dtrace_state_t *state, dtrace_mstate_t *mstate, if (mode & DTRACE_MODE_NOPRIV_DROP) return (0); -#if defined(sun) +#ifdef illumos mstate->dtms_access &= ~DTRACE_ACCESS_PROC; #endif } } -#if defined(sun) +#ifdef illumos /* * If our dte_cond is set to DTRACE_COND_ZONEOWNER and we are not * in our zone, check to see if our mode policy is to restrict rather @@ -3190,7 +3190,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (mstate->dtms_arg[ndx]); -#if defined(sun) +#ifdef illumos case DIF_VAR_UREGS: { klwp_t *lwp; @@ -3246,7 +3246,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } return (mstate->dtms_walltimestamp); -#if defined(sun) +#ifdef illumos case DIF_VAR_IPL: if (!dtrace_priv_kernel(state)) return (0); @@ -3383,7 +3383,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); -#if defined(sun) +#ifdef illumos /* * Note that we are assuming that an unanchored probe is * always due to a high-level interrupt. (And we're assuming @@ -3409,7 +3409,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); -#if defined(sun) +#ifdef illumos /* * See comment in DIF_VAR_PID. */ @@ -3431,7 +3431,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, #endif case DIF_VAR_TID: -#if defined(sun) +#ifdef illumos /* * See comment in DIF_VAR_PID. */ @@ -3452,7 +3452,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } case DIF_VAR_EXECNAME: -#if defined(sun) +#ifdef illumos if (!dtrace_priv_proc(state)) return (0); @@ -3477,7 +3477,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, #endif case DIF_VAR_ZONENAME: -#if defined(sun) +#ifdef illumos if (!dtrace_priv_proc(state)) return (0); @@ -3504,7 +3504,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); -#if defined(sun) +#ifdef illumos /* * See comment in DIF_VAR_PID. */ @@ -3529,7 +3529,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); -#if defined(sun) +#ifdef illumos /* * See comment in DIF_VAR_PID. */ @@ -3551,7 +3551,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, #endif case DIF_VAR_ERRNO: { -#if defined(sun) +#ifdef illumos klwp_t *lwp; if (!dtrace_priv_proc(state)) return (0); @@ -3576,7 +3576,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (curthread->td_errno); #endif } -#if !defined(sun) +#ifndef illumos case DIF_VAR_CPU: { return curcpu; } @@ -4060,7 +4060,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; dtrace_vstate_t *vstate = &state->dts_vstate; -#if defined(sun) +#ifdef illumos union { mutex_impl_t mi; uint64_t mx; @@ -4083,7 +4083,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, regs[rd] = (dtrace_gethrtime() * 2416 + 374441) % 1771875; break; -#if defined(sun) +#ifdef illumos case DIF_SUBR_MUTEX_OWNED: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { @@ -4171,7 +4171,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, regs[rd] = _RW_ISWRITER(&r.ri); break; -#else +#else /* !illumos */ case DIF_SUBR_MUTEX_OWNED: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (struct lock_object), mstate, vstate)) { @@ -4250,7 +4250,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, regs[rd] = LOCK_CLASS(l.li)->lc_owner(l.li, &lowner) && lowner != NULL; break; -#endif /* ! defined(sun) */ +#endif /* illumos */ case DIF_SUBR_BCOPY: { /* @@ -4360,7 +4360,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, break; } -#if defined(sun) +#ifdef illumos case DIF_SUBR_MSGSIZE: case DIF_SUBR_MSGDSIZE: { uintptr_t baddr = tupregs[0].dttk_value, daddr; @@ -4428,7 +4428,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); for (p = curthread->t_procp; p != NULL; p = p->p_parent) { -#if defined(sun) +#ifdef illumos if (p->p_pidp->pid_id == pid) { #else if (p->p_pid == pid) { @@ -4946,7 +4946,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, break; } -#if defined(sun) +#ifdef illumos case DIF_SUBR_GETMAJOR: #ifdef _LP64 regs[rd] = (tupregs[0].dttk_value >> NBITSMINOR64) & MAXMAJ64; @@ -5462,7 +5462,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, uint64_t size = state->dts_options[DTRACEOPT_STRSIZE]; uintptr_t src = tupregs[0].dttk_value; int i = 0, j = 0; -#if defined(sun) +#ifdef illumos zone_t *z; #endif @@ -5564,7 +5564,7 @@ next: dest[j] = '\0'; -#if defined(sun) +#ifdef illumos if (mstate->dtms_getf != NULL && !(mstate->dtms_access & DTRACE_ACCESS_KERNEL) && (z = state->dts_cred.dcr_cred->cr_zone) != kcred->cr_zone) { @@ -5687,7 +5687,7 @@ next: tryzero = -1; numzero = 1; for (i = 0; i < sizeof (struct in6_addr); i++) { -#if defined(sun) +#ifdef illumos if (ip6._S6_un._S6_u8[i] == 0 && #else if (ip6.__u6_addr.__u6_addr8[i] == 0 && @@ -5698,7 +5698,7 @@ next: } if (tryzero != -1 && -#if defined(sun) +#ifdef illumos (ip6._S6_un._S6_u8[i] != 0 || #else (ip6.__u6_addr.__u6_addr8[i] != 0 || @@ -5714,7 +5714,7 @@ next: numzero = i - i % 2 - tryzero; tryzero = -1; -#if defined(sun) +#ifdef illumos if (ip6._S6_un._S6_u8[i] == 0 && #else if (ip6.__u6_addr.__u6_addr8[i] == 0 && @@ -5735,7 +5735,7 @@ next: i >= DTRACE_V4MAPPED_OFFSET; i--) { ASSERT(end >= base); -#if defined(sun) +#ifdef illumos val = ip6._S6_un._S6_u8[i]; #else val = ip6.__u6_addr.__u6_addr8[i]; @@ -5780,7 +5780,7 @@ next: if (i < 14 && i != firstzero - 2) *end-- = ':'; -#if defined(sun) +#ifdef illumos val = (ip6._S6_un._S6_u8[i] << 8) + ip6._S6_un._S6_u8[i + 1]; #else @@ -5826,7 +5826,7 @@ inetout: regs[rd] = (uintptr_t)end + 1; break; } -#if !defined(sun) +#ifndef illumos case DIF_SUBR_MEMSTR: { char *str = (char *)mstate->dtms_scratch_ptr; uintptr_t mem = tupregs[0].dttk_value; @@ -6726,7 +6726,7 @@ dtrace_action_breakpoint(dtrace_ecb_t *ecb) c[i++] = ')'; c[i] = '\0'; -#if defined(sun) +#ifdef illumos debug_enter(c); #else kdb_enter(KDB_WHY_DTRACE, "breakpoint action"); @@ -6773,7 +6773,7 @@ dtrace_action_raise(uint64_t sig) return; } -#if defined(sun) +#ifdef illumos /* * raise() has a queue depth of 1 -- we ignore all subsequent * invocations of the raise() action. @@ -6797,7 +6797,7 @@ dtrace_action_stop(void) if (dtrace_destructive_disallow) return; -#if defined(sun) +#ifdef illumos if (!curthread->t_dtrace_stop) { curthread->t_dtrace_stop = 1; curthread->t_sig_check = 1; @@ -6816,7 +6816,7 @@ dtrace_action_chill(dtrace_mstate_t *mstate, hrtime_t val) { hrtime_t now; volatile uint16_t *flags; -#if defined(sun) +#ifdef illumos cpu_t *cpu = CPU; #else cpu_t *cpu = &solaris_cpu[curcpu]; @@ -7054,7 +7054,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, if (panicstr != NULL) return; -#if defined(sun) +#ifdef illumos /* * Kick out immediately if this CPU is still being born (in which case * curthread will be set to -1) or the current thread can't allow @@ -7079,7 +7079,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, return; } -#if defined(sun) +#ifdef illumos if (panic_quiesce) { #else if (panicstr != NULL) { @@ -7186,7 +7186,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, probe->dtpr_id, probe->dtpr_arg) == 0) continue; -#if defined(sun) +#ifdef illumos /* * This is more subtle than it looks. We have to be * absolutely certain that CRED() isn't going to @@ -7611,7 +7611,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, case DTRACEACT_USYM: case DTRACEACT_UMOD: case DTRACEACT_UADDR: { -#if defined(sun) +#ifdef illumos struct pid *pid = curthread->t_procp->p_pidp; #endif @@ -7619,7 +7619,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, continue; DTRACE_STORE(uint64_t, tomax, -#if defined(sun) +#ifdef illumos valoffs, (uint64_t)pid->pid_id); #else valoffs, (uint64_t) curproc->p_pid); @@ -8044,7 +8044,7 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp) { uint32_t priv; -#if defined(sun) +#ifdef illumos if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) { /* * For DTRACE_PRIV_ALL, the uid and zoneid don't matter. @@ -8638,7 +8638,7 @@ dtrace_unregister(dtrace_provider_id_t id) * already held. */ ASSERT(old == dtrace_provider); -#if defined(sun) +#ifdef illumos ASSERT(dtrace_devi != NULL); #endif ASSERT(MUTEX_HELD(&dtrace_provider_lock)); @@ -8653,7 +8653,7 @@ dtrace_unregister(dtrace_provider_id_t id) } } else { mutex_enter(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_enter(&mod_lock); #endif mutex_enter(&dtrace_lock); @@ -8669,7 +8669,7 @@ dtrace_unregister(dtrace_provider_id_t id) dtrace_anon.dta_state->dts_necbs > 0))) { if (!self) { mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -8705,7 +8705,7 @@ dtrace_unregister(dtrace_provider_id_t id) if (!self) { mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -8761,7 +8761,7 @@ dtrace_unregister(dtrace_provider_id_t id) kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1); kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1); kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1); -#if defined(sun) +#ifdef illumos vmem_free(dtrace_arena, (void *)(uintptr_t)(probe->dtpr_id), 1); #else free_unr(dtrace_arena, probe->dtpr_id); @@ -8770,7 +8770,7 @@ dtrace_unregister(dtrace_provider_id_t id) } if ((prev = dtrace_provider) == old) { -#if defined(sun) +#ifdef illumos ASSERT(self || dtrace_devi == NULL); ASSERT(old->dtpv_next == NULL || dtrace_devi == NULL); #endif @@ -8789,7 +8789,7 @@ dtrace_unregister(dtrace_provider_id_t id) if (!self) { mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -8882,7 +8882,7 @@ dtrace_condense(dtrace_provider_id_t id) kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1); kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1); kmem_free(probe, sizeof (dtrace_probe_t)); -#if defined(sun) +#ifdef illumos vmem_free(dtrace_arena, (void *)((uintptr_t)i + 1), 1); #else free_unr(dtrace_arena, i + 1); @@ -8922,7 +8922,7 @@ dtrace_probe_create(dtrace_provider_id_t prov, const char *mod, mutex_enter(&dtrace_lock); } -#if defined(sun) +#ifdef illumos id = (dtrace_id_t)(uintptr_t)vmem_alloc(dtrace_arena, 1, VM_BESTFIT | VM_SLEEP); #else @@ -9093,7 +9093,7 @@ dtrace_probe_description(const dtrace_probe_t *prp, dtrace_probedesc_t *pdp) static void dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) { -#if defined(sun) +#ifdef illumos modctl_t *ctl; #endif int all = 0; @@ -9111,7 +9111,7 @@ dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) */ prv->dtpv_pops.dtps_provide(prv->dtpv_arg, desc); -#if defined(sun) +#ifdef illumos /* * Now call the per-module provide operation. We will grab * mod_lock to prevent the list from being modified. Note @@ -9134,7 +9134,7 @@ dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) } while (all && (prv = prv->dtpv_next) != NULL); } -#if defined(sun) +#ifdef illumos /* * Iterate over each probe, and call the Framework-to-Provider API function * denoted by offs. @@ -10092,7 +10092,7 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp) subr == DIF_SUBR_NTOHL || subr == DIF_SUBR_NTOHLL || subr == DIF_SUBR_MEMREF || -#if !defined(sun) +#ifndef illumos subr == DIF_SUBR_MEMSTR || #endif subr == DIF_SUBR_TYPEREF) @@ -10730,7 +10730,7 @@ dtrace_actdesc_create(dtrace_actkind_t kind, uint32_t ntuple, { dtrace_actdesc_t *act; -#if defined(sun) +#ifdef illumos ASSERT(!DTRACEACT_ISPRINTFLIKE(kind) || (arg != NULL && arg >= KERNELBASE) || (arg == NULL && kind == DTRACEACT_PRINTA)); #endif @@ -10769,7 +10769,7 @@ dtrace_actdesc_release(dtrace_actdesc_t *act, dtrace_vstate_t *vstate) if (DTRACEACT_ISPRINTFLIKE(kind)) { char *str = (char *)(uintptr_t)act->dtad_arg; -#if defined(sun) +#ifdef illumos ASSERT((str != NULL && (uintptr_t)str >= KERNELBASE) || (str == NULL && act->dtad_kind == DTRACEACT_PRINTA)); #endif @@ -11128,7 +11128,7 @@ success: /* * We need to allocate an id for this aggregation. */ -#if defined(sun) +#ifdef illumos aggid = (dtrace_aggid_t)(uintptr_t)vmem_alloc(state->dts_aggid_arena, 1, VM_BESTFIT | VM_SLEEP); #else @@ -11182,7 +11182,7 @@ dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act) dtrace_aggid_t aggid = agg->dtag_id; ASSERT(DTRACEACT_ISAGG(act->dta_kind)); -#if defined(sun) +#ifdef illumos vmem_free(state->dts_aggid_arena, (void *)(uintptr_t)aggid, 1); #else free_unr(state->dts_aggid_arena, aggid); @@ -11251,7 +11251,7 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) format = 0; } else { ASSERT(arg != 0); -#if defined(sun) +#ifdef illumos ASSERT(arg > KERNELBASE); #endif format = dtrace_format_add(state, @@ -11803,13 +11803,13 @@ static int dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags, processorid_t cpu, int *factor) { -#if defined(sun) +#ifdef illumos cpu_t *cp; #endif dtrace_buffer_t *buf; int allocated = 0, desired = 0; -#if defined(sun) +#ifdef illumos ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(MUTEX_HELD(&dtrace_lock)); @@ -12680,7 +12680,7 @@ dtrace_enabling_matchall(void) * block pending our completion. */ for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) { -#if defined(sun) +#ifdef illumos cred_t *cr = enab->dten_vstate->dtvs_state->dts_cred.dcr_cred; if (INGLOBALZONE(curproc) || @@ -12985,7 +12985,7 @@ dtrace_dof_copyin(uintptr_t uarg, int *errp) return (dof); } -#if !defined(sun) +#ifndef illumos static __inline uchar_t dtrace_dof_char(char c) { switch (c) { @@ -13028,7 +13028,7 @@ dtrace_dof_property(const char *name) unsigned int len, i; dof_hdr_t *dof; -#if defined(sun) +#ifdef illumos /* * Unfortunately, array of values in .conf files are always (and * only) interpreted to be integer arrays. We must read our DOF @@ -13984,7 +13984,7 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) maxper = (limit - (uintptr_t)start) / NCPU; maxper = (maxper / dstate->dtds_chunksize) * dstate->dtds_chunksize; -#if !defined(sun) +#ifndef illumos CPU_FOREACH(i) { #else for (i = 0; i < NCPU; i++) { @@ -14064,7 +14064,7 @@ dtrace_vstate_fini(dtrace_vstate_t *vstate) } } -#if defined(sun) +#ifdef illumos static void dtrace_state_clean(dtrace_state_t *state) { @@ -14101,7 +14101,7 @@ dtrace_state_deadman(dtrace_state_t *state) dtrace_membar_producer(); state->dts_alive = now; } -#else +#else /* !illumos */ static void dtrace_state_clean(void *arg) { @@ -14150,16 +14150,16 @@ dtrace_state_deadman(void *arg) callout_reset(&state->dts_deadman, hz * dtrace_deadman_interval / NANOSEC, dtrace_state_deadman, state); } -#endif +#endif /* illumos */ static dtrace_state_t * -#if defined(sun) +#ifdef illumos dtrace_state_create(dev_t *devp, cred_t *cr) #else dtrace_state_create(struct cdev *dev) #endif { -#if defined(sun) +#ifdef illumos minor_t minor; major_t major; #else @@ -14174,7 +14174,7 @@ dtrace_state_create(struct cdev *dev) ASSERT(MUTEX_HELD(&dtrace_lock)); ASSERT(MUTEX_HELD(&cpu_lock)); -#if defined(sun) +#ifdef illumos minor = (minor_t)(uintptr_t)vmem_alloc(dtrace_minor, 1, VM_BESTFIT | VM_SLEEP); @@ -14197,7 +14197,7 @@ dtrace_state_create(struct cdev *dev) state->dts_epid = DTRACE_EPIDNONE + 1; (void) snprintf(c, sizeof (c), "dtrace_aggid_%d", m); -#if defined(sun) +#ifdef illumos state->dts_aggid_arena = vmem_create(c, (void *)1, UINT32_MAX, 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER); @@ -14225,7 +14225,7 @@ dtrace_state_create(struct cdev *dev) state->dts_buffer = kmem_zalloc(bufsize, KM_SLEEP); state->dts_aggbuffer = kmem_zalloc(bufsize, KM_SLEEP); -#if defined(sun) +#ifdef illumos state->dts_cleaner = CYCLIC_NONE; state->dts_deadman = CYCLIC_NONE; #else @@ -14315,7 +14315,7 @@ dtrace_state_create(struct cdev *dev) * we can do destructive things to processes which * have altered credentials. */ -#if defined(sun) +#ifdef illumos if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE), cr->cr_zone->zone_privset)) { state->dts_cred.dcr_action |= @@ -14357,7 +14357,7 @@ dtrace_state_create(struct cdev *dev) state->dts_cred.dcr_action |= DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE; -#if defined(sun) +#ifdef illumos /* * If we have all privs in whatever zone this is, * we can do destructive things to processes which @@ -14516,7 +14516,7 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) dtrace_optval_t *opt = state->dts_options, sz, nspec; dtrace_speculation_t *spec; dtrace_buffer_t *buf; -#if defined(sun) +#ifdef illumos cyc_handler_t hdlr; cyc_time_t when; #endif @@ -14700,7 +14700,7 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_max; state->dts_alive = state->dts_laststatus = dtrace_gethrtime(); -#if defined(sun) +#ifdef illumos hdlr.cyh_func = (cyc_func_t)dtrace_state_clean; hdlr.cyh_arg = state; hdlr.cyh_level = CY_LOW_LEVEL; @@ -14727,7 +14727,7 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) state->dts_activity = DTRACE_ACTIVITY_WARMUP; -#if defined(sun) +#ifdef illumos if (state->dts_getf != 0 && !(state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL)) { /* @@ -14861,7 +14861,7 @@ dtrace_state_stop(dtrace_state_t *state, processorid_t *cpu) state->dts_activity = DTRACE_ACTIVITY_STOPPED; dtrace_sync(); -#if defined(sun) +#ifdef illumos if (state->dts_getf != 0 && !(state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL)) { /* @@ -14944,7 +14944,7 @@ dtrace_state_destroy(dtrace_state_t *state) { dtrace_ecb_t *ecb; dtrace_vstate_t *vstate = &state->dts_vstate; -#if defined(sun) +#ifdef illumos minor_t minor = getminor(state->dts_dev); #endif int i, bufsize = NCPU * sizeof (dtrace_buffer_t); @@ -15022,7 +15022,7 @@ dtrace_state_destroy(dtrace_state_t *state) for (i = 0; i < nspec; i++) dtrace_buffer_free(spec[i].dtsp_buffer); -#if defined(sun) +#ifdef illumos if (state->dts_cleaner != CYCLIC_NONE) cyclic_remove(state->dts_cleaner); @@ -15062,14 +15062,14 @@ dtrace_state_destroy(dtrace_state_t *state) dtrace_format_destroy(state); if (state->dts_aggid_arena != NULL) { -#if defined(sun) +#ifdef illumos vmem_destroy(state->dts_aggid_arena); #else delete_unrhdr(state->dts_aggid_arena); #endif state->dts_aggid_arena = NULL; } -#if defined(sun) +#ifdef illumos ddi_soft_state_free(dtrace_softstate, minor); vmem_free(dtrace_minor, (void *)(uintptr_t)minor, 1); #endif @@ -15121,7 +15121,7 @@ dtrace_anon_property(void) break; } -#if defined(sun) +#ifdef illumos /* * We want to create anonymous state, so we need to transition * the kernel debugger to indicate that DTrace is active. If @@ -15140,7 +15140,7 @@ dtrace_anon_property(void) * If we haven't allocated an anonymous state, we'll do so now. */ if ((state = dtrace_anon.dta_state) == NULL) { -#if defined(sun) +#ifdef illumos state = dtrace_state_create(NULL, NULL); #else state = dtrace_state_create(NULL); @@ -16031,7 +16031,7 @@ dtrace_helpers_create(proc_t *p) return (help); } -#if defined(sun) +#ifdef illumos static #endif void @@ -16039,7 +16039,7 @@ dtrace_helpers_destroy(proc_t *p) { dtrace_helpers_t *help; dtrace_vstate_t *vstate; -#if defined(sun) +#ifdef illumos proc_t *p = curproc; #endif int i; @@ -16128,7 +16128,7 @@ dtrace_helpers_destroy(proc_t *p) mutex_exit(&dtrace_lock); } -#if defined(sun) +#ifdef illumos static #endif void @@ -16222,11 +16222,11 @@ dtrace_module_loaded(modctl_t *ctl) dtrace_provider_t *prv; mutex_enter(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_enter(&mod_lock); #endif -#if defined(sun) +#ifdef illumos ASSERT(ctl->mod_busy); #endif @@ -16237,7 +16237,7 @@ dtrace_module_loaded(modctl_t *ctl) for (prv = dtrace_provider; prv != NULL; prv = prv->dtpv_next) prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -16276,7 +16276,7 @@ dtrace_module_loaded(modctl_t *ctl) } static void -#if defined(sun) +#ifdef illumos dtrace_module_unloaded(modctl_t *ctl) #else dtrace_module_unloaded(modctl_t *ctl, int *error) @@ -16284,12 +16284,12 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) { dtrace_probe_t template, *probe, *first, *next; dtrace_provider_t *prov; -#if !defined(sun) +#ifndef illumos char modname[DTRACE_MODNAMELEN]; size_t len; #endif -#if defined(sun) +#ifdef illumos template.dtpr_mod = ctl->mod_modname; #else /* Handle the fact that ctl->filename may end in ".ko". */ @@ -16301,12 +16301,12 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) #endif mutex_enter(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_enter(&mod_lock); #endif mutex_enter(&dtrace_lock); -#if !defined(sun) +#ifndef illumos if (ctl->nenabled > 0) { /* Don't allow unloads if a probe is enabled. */ mutex_exit(&dtrace_provider_lock); @@ -16324,7 +16324,7 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) * we don't have any work to do. */ mutex_exit(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_lock); @@ -16335,7 +16335,7 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) probe != NULL; probe = probe->dtpr_nextmod) { if (probe->dtpr_ecb != NULL) { mutex_exit(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_lock); @@ -16351,7 +16351,7 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) * probe, either. */ if (dtrace_err_verbose) { -#if defined(sun) +#ifdef illumos cmn_err(CE_WARN, "unloaded module '%s' had " "enabled probes", ctl->mod_modname); #else @@ -16400,7 +16400,7 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1); kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1); kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1); -#if defined(sun) +#ifdef illumos vmem_free(dtrace_arena, (void *)(uintptr_t)probe->dtpr_id, 1); #else free_unr(dtrace_arena, probe->dtpr_id); @@ -16409,13 +16409,13 @@ dtrace_module_unloaded(modctl_t *ctl, int *error) } mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); } -#if !defined(sun) +#ifndef illumos static void dtrace_kld_load(void *arg __unused, linker_file_t lf) { @@ -16434,7 +16434,7 @@ dtrace_kld_unload_try(void *arg __unused, linker_file_t lf, int *error) } #endif -#if defined(sun) +#ifdef illumos static void dtrace_suspend(void) { @@ -16507,7 +16507,7 @@ dtrace_cpu_setup(cpu_setup_t what, processorid_t cpu) return (0); } -#if defined(sun) +#ifdef illumos static void dtrace_cpu_setup_initial(processorid_t cpu) { @@ -16555,7 +16555,7 @@ dtrace_toxrange_add(uintptr_t base, uintptr_t limit) static void dtrace_getf_barrier() { -#if defined(sun) +#ifdef illumos /* * When we have unprivileged (that is, non-DTRACE_CRV_KERNEL) enablings * that contain calls to getf(), this routine will be called on every @@ -16574,7 +16574,7 @@ dtrace_getf_barrier() /* * DTrace Driver Cookbook Functions */ -#if defined(sun) +#ifdef illumos /*ARGSUSED*/ static int dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) @@ -16730,15 +16730,15 @@ dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) return (DDI_SUCCESS); } -#endif +#endif /* illumos */ -#if !defined(sun) +#ifndef illumos static void dtrace_dtr(void *); #endif /*ARGSUSED*/ static int -#if defined(sun) +#ifdef illumos dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) #else dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) @@ -16749,7 +16749,7 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) uid_t uid; zoneid_t zoneid; -#if defined(sun) +#ifdef illumos if (getminor(*devp) == DTRACEMNRN_HELPER) return (0); @@ -16786,7 +16786,7 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) dtrace_opens++; dtrace_membar_producer(); -#if defined(sun) +#ifdef illumos /* * If the kernel debugger is active (that is, if the kernel debugger * modified text in some way), we won't allow the open. @@ -16819,7 +16819,7 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) mutex_exit(&cpu_lock); if (state == NULL) { -#if defined(sun) +#ifdef illumos if (--dtrace_opens == 0 && dtrace_anon.dta_enabling == NULL) (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE); #else @@ -16835,7 +16835,7 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) } /*ARGSUSED*/ -#if defined(sun) +#ifdef illumos static int dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p) #else @@ -16843,7 +16843,7 @@ static void dtrace_dtr(void *data) #endif { -#if defined(sun) +#ifdef illumos minor_t minor = getminor(dev); dtrace_state_t *state; #endif @@ -16896,7 +16896,7 @@ dtrace_dtr(void *data) #endif ASSERT(dtrace_opens > 0); -#if defined(sun) +#ifdef illumos /* * Only relinquish control of the kernel debugger interface when there * are no consumers and no anonymous enablings. @@ -16915,12 +16915,12 @@ dtrace_dtr(void *data) mutex_exit(&dtrace_lock); mutex_exit(&cpu_lock); -#if defined(sun) +#ifdef illumos return (0); #endif } -#if defined(sun) +#ifdef illumos /*ARGSUSED*/ static int dtrace_ioctl_helper(int cmd, intptr_t arg, int *rv) @@ -17859,7 +17859,7 @@ dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) } #endif -#if defined(sun) +#ifdef illumos /*ARGSUSED*/ static int dtrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) @@ -17882,7 +17882,7 @@ dtrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) } #endif -#if defined(sun) +#ifdef illumos static struct cb_ops dtrace_cb_ops = { dtrace_open, /* open */ dtrace_close, /* close */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c index 19fb43c..84b72d2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c @@ -38,13 +38,13 @@ #include <sys/modctl.h> #include <sys/conf.h> #include <sys/systm.h> -#if defined(sun) +#ifdef illumos #include <sys/ddi.h> #endif #include <sys/sunddi.h> #include <sys/cpuvar.h> #include <sys/kmem.h> -#if defined(sun) +#ifdef illumos #include <sys/strsubr.h> #endif #include <sys/fasttrap.h> @@ -55,12 +55,12 @@ #include <sys/sysmacros.h> #include <sys/proc.h> #include <sys/policy.h> -#if defined(sun) +#ifdef illumos #include <util/qsort.h> #endif #include <sys/mutex.h> #include <sys/kernel.h> -#if !defined(sun) +#ifndef illumos #include <sys/dtrace_bsd.h> #include <sys/eventhandler.h> #include <sys/sysctl.h> @@ -215,7 +215,7 @@ static void fasttrap_provider_free(fasttrap_provider_t *); static fasttrap_proc_t *fasttrap_proc_lookup(pid_t); static void fasttrap_proc_release(fasttrap_proc_t *); -#if !defined(sun) +#ifndef illumos static void fasttrap_thread_dtor(void *, struct thread *); #endif @@ -224,7 +224,7 @@ static void fasttrap_thread_dtor(void *, struct thread *); #define FASTTRAP_PROCS_INDEX(pid) ((pid) & fasttrap_procs.fth_mask) -#if !defined(sun) +#ifndef illumos static kmutex_t fasttrap_cpuc_pid_lock[MAXCPU]; static eventhandler_tag fasttrap_thread_dtor_tag; #endif @@ -288,7 +288,7 @@ fasttrap_hash_str(const char *p) void fasttrap_sigtrap(proc_t *p, kthread_t *t, uintptr_t pc) { -#if defined(sun) +#ifdef illumos sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); sqp->sq_info.si_signo = SIGTRAP; @@ -314,7 +314,7 @@ fasttrap_sigtrap(proc_t *p, kthread_t *t, uintptr_t pc) #endif } -#if !defined(sun) +#ifndef illumos /* * Obtain a chunk of scratch space in the address space of the target process. */ @@ -586,20 +586,20 @@ fasttrap_pid_cleanup(void) static void fasttrap_fork(proc_t *p, proc_t *cp) { -#if !defined(sun) +#ifndef illumos fasttrap_scrblock_t *scrblk; fasttrap_proc_t *fprc = NULL; #endif pid_t ppid = p->p_pid; int i; -#if defined(sun) +#ifdef illumos ASSERT(curproc == p); ASSERT(p->p_proc_flag & P_PR_LOCK); #else PROC_LOCK_ASSERT(p, MA_OWNED); #endif -#if defined(sun) +#ifdef illumos ASSERT(p->p_dtrace_count > 0); #else if (p->p_dtrace_helpers) { @@ -638,7 +638,7 @@ fasttrap_fork(proc_t *p, proc_t *cp) * We don't have to worry about the child process disappearing * because we're in fork(). */ -#if defined(sun) +#ifdef illumos mtx_lock_spin(&cp->p_slock); sprlock_proc(cp); mtx_unlock_spin(&cp->p_slock); @@ -675,14 +675,14 @@ fasttrap_fork(proc_t *p, proc_t *cp) * mid-fork. */ ASSERT(tp->ftt_proc->ftpc_acount != 0); -#if !defined(sun) +#ifndef illumos fprc = tp->ftt_proc; #endif } } mutex_exit(&bucket->ftb_mtx); -#if !defined(sun) +#ifndef illumos /* * Unmap any scratch space inherited from the parent's address * space. @@ -699,7 +699,7 @@ fasttrap_fork(proc_t *p, proc_t *cp) #endif } -#if defined(sun) +#ifdef illumos mutex_enter(&cp->p_lock); sprunlock(cp); #else @@ -717,11 +717,11 @@ fasttrap_fork(proc_t *p, proc_t *cp) static void fasttrap_exec_exit(proc_t *p) { -#if !defined(sun) +#ifndef illumos struct thread *td; #endif -#if defined(sun) +#ifdef illumos ASSERT(p == curproc); #else PROC_LOCK_ASSERT(p, MA_OWNED); @@ -741,7 +741,7 @@ fasttrap_exec_exit(proc_t *p) * static probes are handled by the meta-provider remove entry point. */ fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0); -#if !defined(sun) +#ifndef illumos if (p->p_dtrace_helpers) dtrace_helpers_destroy(p); PROC_LOCK(p); @@ -776,7 +776,7 @@ fasttrap_tracepoint_enable(proc_t *p, fasttrap_probe_t *probe, uint_t index) ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid); -#if defined(sun) +#ifdef illumos ASSERT(!(p->p_flag & SVFORK)); #endif @@ -884,7 +884,7 @@ again: * Increment the count of the number of tracepoints active in * the victim process. */ -#if defined(sun) +#ifdef illumos ASSERT(p->p_proc_flag & P_PR_LOCK); #endif p->p_dtrace_count++; @@ -1076,7 +1076,7 @@ fasttrap_tracepoint_disable(proc_t *p, fasttrap_probe_t *probe, uint_t index) * Decrement the count of the number of tracepoints active * in the victim process. */ -#if defined(sun) +#ifdef illumos ASSERT(p->p_proc_flag & P_PR_LOCK); #endif p->p_dtrace_count--; @@ -1129,7 +1129,7 @@ fasttrap_enable_callbacks(void) static void fasttrap_disable_callbacks(void) { -#if defined(sun) +#ifdef illumos ASSERT(MUTEX_HELD(&cpu_lock)); #endif @@ -1138,7 +1138,7 @@ fasttrap_disable_callbacks(void) ASSERT(fasttrap_pid_count > 0); fasttrap_pid_count--; if (fasttrap_pid_count == 0) { -#if defined(sun) +#ifdef illumos cpu_t *cur, *cpu = CPU; for (cur = cpu->cpu_next_onln; cur != cpu; @@ -1148,7 +1148,7 @@ fasttrap_disable_callbacks(void) #endif dtrace_pid_probe_ptr = NULL; dtrace_return_probe_ptr = NULL; -#if defined(sun) +#ifdef illumos for (cur = cpu->cpu_next_onln; cur != cpu; cur = cur->cpu_next_onln) { rw_exit(&cur->cpu_ft_lock); @@ -1169,7 +1169,7 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) ASSERT(probe != NULL); ASSERT(!probe->ftp_enabled); ASSERT(id == probe->ftp_id); -#if defined(sun) +#ifdef illumos ASSERT(MUTEX_HELD(&cpu_lock)); #endif @@ -1196,7 +1196,7 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) * a fork in which the traced process is being born and we're copying * USDT probes. Otherwise, the process is gone so bail. */ -#if defined(sun) +#ifdef illumos if ((p = sprlock(probe->ftp_pid)) == NULL) { if ((curproc->p_flag & SFORKING) == 0) return; @@ -1264,7 +1264,7 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) i--; } -#if defined(sun) +#ifdef illumos mutex_enter(&p->p_lock); sprunlock(p); #else @@ -1279,7 +1279,7 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) return; } } -#if defined(sun) +#ifdef illumos mutex_enter(&p->p_lock); sprunlock(p); #else @@ -1363,7 +1363,7 @@ fasttrap_pid_disable(void *arg, dtrace_id_t id, void *parg) probe->ftp_enabled = 0; -#if defined(sun) +#ifdef illumos ASSERT(MUTEX_HELD(&cpu_lock)); #endif fasttrap_disable_callbacks(); @@ -1504,7 +1504,7 @@ fasttrap_proc_lookup(pid_t pid) new_fprc->ftpc_pid = pid; new_fprc->ftpc_rcount = 1; new_fprc->ftpc_acount = 1; -#if !defined(sun) +#ifndef illumos mutex_init(&new_fprc->ftpc_mtx, "fasttrap proc mtx", MUTEX_DEFAULT, NULL); #endif @@ -1544,7 +1544,7 @@ fasttrap_proc_release(fasttrap_proc_t *proc) fasttrap_bucket_t *bucket; fasttrap_proc_t *fprc, **fprcp; pid_t pid = proc->ftpc_pid; -#if !defined(sun) +#ifndef illumos fasttrap_scrblock_t *scrblk, *scrblktmp; fasttrap_scrspace_t *scrspc, *scrspctmp; struct proc *p; @@ -1561,7 +1561,7 @@ fasttrap_proc_release(fasttrap_proc_t *proc) return; } -#if !defined(sun) +#ifndef illumos /* * Free all structures used to manage per-thread scratch space. */ @@ -1683,7 +1683,7 @@ fasttrap_provider_lookup(pid_t pid, const char *name, new_fp = kmem_zalloc(sizeof (fasttrap_provider_t), KM_SLEEP); new_fp->ftp_pid = pid; new_fp->ftp_proc = fasttrap_proc_lookup(pid); -#if !defined(sun) +#ifndef illumos mutex_init(&new_fp->ftp_mtx, "provider mtx", MUTEX_DEFAULT, NULL); mutex_init(&new_fp->ftp_cmtx, "lock on creating", MUTEX_DEFAULT, NULL); #endif @@ -1764,7 +1764,7 @@ fasttrap_provider_free(fasttrap_provider_t *provider) fasttrap_proc_release(provider->ftp_proc); -#if !defined(sun) +#ifndef illumos mutex_destroy(&provider->ftp_mtx); mutex_destroy(&provider->ftp_cmtx); #endif @@ -1782,7 +1782,7 @@ fasttrap_provider_free(fasttrap_provider_t *provider) } p->p_dtrace_probes--; -#if !defined(sun) +#ifndef illumos PROC_UNLOCK(p); #endif } @@ -2323,7 +2323,7 @@ fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag, proc_t *p; pid_t pid = probe->ftps_pid; -#if defined(sun) +#ifdef illumos mutex_enter(&pidlock); #endif /* @@ -2334,12 +2334,12 @@ fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag, if (p) fill_kinfo_proc(p, &kp); if (p == NULL || kp.ki_stat == SIDL) { -#if defined(sun) +#ifdef illumos mutex_exit(&pidlock); #endif return (ESRCH); } -#if defined(sun) +#ifdef illumos mutex_enter(&p->p_lock); mutex_exit(&pidlock); #else @@ -2349,7 +2349,7 @@ fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag, #ifdef notyet if ((ret = priv_proc_cred_perm(cr, p, NULL, VREAD | VWRITE)) != 0) { -#if defined(sun) +#ifdef illumos mutex_exit(&p->p_lock); #else PROC_UNLOCK(p); @@ -2357,7 +2357,7 @@ fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag, return (ret); } #endif /* notyet */ -#if defined(sun) +#ifdef illumos mutex_exit(&p->p_lock); #else PROC_UNLOCK(p); @@ -2375,11 +2375,11 @@ err: fasttrap_instr_query_t instr; fasttrap_tracepoint_t *tp; uint_t index; -#if defined(sun) +#ifdef illumos int ret; #endif -#if defined(sun) +#ifdef illumos if (copyin((void *)arg, &instr, sizeof (instr)) != 0) return (EFAULT); #endif @@ -2389,7 +2389,7 @@ err: proc_t *p; pid_t pid = instr.ftiq_pid; -#if defined(sun) +#ifdef illumos mutex_enter(&pidlock); #endif /* @@ -2400,12 +2400,12 @@ err: if (p) fill_kinfo_proc(p, &kp); if (p == NULL || kp.ki_stat == SIDL) { -#if defined(sun) +#ifdef illumos mutex_exit(&pidlock); #endif return (ESRCH); } -#if defined(sun) +#ifdef illumos mutex_enter(&p->p_lock); mutex_exit(&pidlock); #else @@ -2415,7 +2415,7 @@ err: #ifdef notyet if ((ret = priv_proc_cred_perm(cr, p, NULL, VREAD)) != 0) { -#if defined(sun) +#ifdef illumos mutex_exit(&p->p_lock); #else PROC_UNLOCK(p); @@ -2424,7 +2424,7 @@ err: } #endif /* notyet */ -#if defined(sun) +#ifdef illumos mutex_exit(&p->p_lock); #else PROC_UNLOCK(p); @@ -2477,7 +2477,7 @@ fasttrap_load(void) mutex_init(&fasttrap_count_mtx, "fasttrap count mtx", MUTEX_DEFAULT, NULL); -#if defined(sun) +#ifdef illumos fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, "fasttrap-max-probes", FASTTRAP_MAX_DEFAULT); #endif @@ -2486,7 +2486,7 @@ fasttrap_load(void) /* * Conjure up the tracepoints hashtable... */ -#if defined(sun) +#ifdef illumos nent = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, "fasttrap-hash-size", FASTTRAP_TPOINTS_DEFAULT_SIZE); #else @@ -2506,7 +2506,7 @@ fasttrap_load(void) fasttrap_tpoints.fth_mask = fasttrap_tpoints.fth_nent - 1; fasttrap_tpoints.fth_table = kmem_zalloc(fasttrap_tpoints.fth_nent * sizeof (fasttrap_bucket_t), KM_SLEEP); -#if !defined(sun) +#ifndef illumos for (i = 0; i < fasttrap_tpoints.fth_nent; i++) mutex_init(&fasttrap_tpoints.fth_table[i].ftb_mtx, "tracepoints bucket mtx", MUTEX_DEFAULT, NULL); @@ -2524,7 +2524,7 @@ fasttrap_load(void) fasttrap_provs.fth_mask = fasttrap_provs.fth_nent - 1; fasttrap_provs.fth_table = kmem_zalloc(fasttrap_provs.fth_nent * sizeof (fasttrap_bucket_t), KM_SLEEP); -#if !defined(sun) +#ifndef illumos for (i = 0; i < fasttrap_provs.fth_nent; i++) mutex_init(&fasttrap_provs.fth_table[i].ftb_mtx, "providers bucket mtx", MUTEX_DEFAULT, NULL); @@ -2534,7 +2534,7 @@ fasttrap_load(void) &fasttrap_cleanup_proc, 0, 0, "ftcleanup"); if (ret != 0) { destroy_dev(fasttrap_cdev); -#if !defined(sun) +#ifndef illumos for (i = 0; i < fasttrap_provs.fth_nent; i++) mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx); for (i = 0; i < fasttrap_tpoints.fth_nent; i++) @@ -2560,7 +2560,7 @@ fasttrap_load(void) fasttrap_procs.fth_mask = fasttrap_procs.fth_nent - 1; fasttrap_procs.fth_table = kmem_zalloc(fasttrap_procs.fth_nent * sizeof (fasttrap_bucket_t), KM_SLEEP); -#if !defined(sun) +#ifndef illumos for (i = 0; i < fasttrap_procs.fth_nent; i++) mutex_init(&fasttrap_procs.fth_table[i].ftb_mtx, "processes bucket mtx", MUTEX_DEFAULT, NULL); @@ -2676,7 +2676,7 @@ fasttrap_unload(void) mutex_exit(&fasttrap_count_mtx); #endif -#if !defined(sun) +#ifndef illumos EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor_tag); for (i = 0; i < fasttrap_tpoints.fth_nent; i++) @@ -2698,7 +2698,7 @@ fasttrap_unload(void) fasttrap_procs.fth_nent * sizeof (fasttrap_bucket_t)); fasttrap_procs.fth_nent = 0; -#if !defined(sun) +#ifndef illumos destroy_dev(fasttrap_cdev); mutex_destroy(&fasttrap_count_mtx); CPU_FOREACH(i) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c b/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c index 4bcdfc6..2ff8df6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c @@ -107,7 +107,7 @@ * gfs_root_create_file() */ -#ifdef sun +#ifdef illumos /* * gfs_make_opsvec: take an array of vnode type definitions and create * their vnodeops_t structures @@ -141,7 +141,7 @@ gfs_make_opsvec(gfs_opsvec_t *vec) } return (error); } -#endif /* sun */ +#endif /* illumos */ /* * Low level directory routines @@ -347,7 +347,7 @@ gfs_readdir_emit(gfs_readdir_state_t *st, uio_t *uiop, offset_t voff, cookies)); } -#ifdef sun +#ifdef illumos /* * gfs_readdir_emitn: like gfs_readdir_emit(), but takes an integer * instead of a string for the entry's name. @@ -599,7 +599,7 @@ gfs_root_create(size_t size, vfs_t *vfsp, vnodeops_t *ops, ino64_t ino, return (vp); } -#ifdef sun +#ifdef illumos /* * gfs_root_create_file(): create a root vnode for a GFS file as a filesystem * @@ -619,7 +619,7 @@ gfs_root_create_file(size_t size, vfs_t *vfsp, vnodeops_t *ops, ino64_t ino) return (vp); } -#endif /* sun */ +#endif /* illumos */ /* * gfs_file_inactive() @@ -1146,7 +1146,7 @@ gfs_vop_readdir(ap) } -#ifdef sun +#ifdef illumos /* * gfs_vop_map: VOP_MAP() entry point * @@ -1218,7 +1218,7 @@ gfs_vop_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, return (rv); } -#endif /* sun */ +#endif /* illumos */ /* * gfs_vop_reclaim: VOP_RECLAIM() entry point (solaris' VOP_INACTIVE()) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 29ef565..6d99a79 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1610,7 +1610,7 @@ arc_cksum_compute(arc_buf_t *buf, boolean_t force) mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); #ifdef illumos arc_buf_watch(buf); -#endif /* illumos */ +#endif } #ifdef illumos @@ -1713,7 +1713,7 @@ arc_buf_thaw(arc_buf_t *buf) #ifdef illumos arc_buf_unwatch(buf); -#endif /* illumos */ +#endif } void @@ -2287,7 +2287,7 @@ arc_buf_destroy(arc_buf_t *buf, boolean_t remove) arc_cksum_verify(buf); #ifdef illumos arc_buf_unwatch(buf); -#endif /* illumos */ +#endif if (type == ARC_BUFC_METADATA) { arc_buf_data_free(buf, zio_buf_free); @@ -3412,7 +3412,7 @@ arc_available_memory(void) r = FMR_LOTSFREE; } -#ifdef sun +#ifdef illumos /* * check that we're out of range of the pageout scanner. It starts to * schedule paging if freemem is less than lotsfree and needfree. @@ -3455,7 +3455,7 @@ arc_available_memory(void) r = FMR_PAGES_PP_MAXIMUM; } -#endif /* sun */ +#endif /* illumos */ #if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC) /* * If we're on an i386 platform, it's possible that we'll exhaust the @@ -3578,7 +3578,7 @@ arc_kmem_reap_now(void) kmem_cache_reap_now(hdr_l2only_cache); kmem_cache_reap_now(range_seg_cache); -#ifdef sun +#ifdef illumos if (zio_arena != NULL) { /* * Ask the vmem arena to reclaim unused memory from its @@ -3609,7 +3609,7 @@ arc_kmem_reap_now(void) static void arc_reclaim_thread(void *dummy __unused) { - clock_t growtime = 0; + hrtime_t growtime = 0; callb_cpr_t cpr; CALLB_CPR_INIT(&cpr, &arc_reclaim_lock, callb_generic_cpr, FTAG); @@ -3630,7 +3630,7 @@ arc_reclaim_thread(void *dummy __unused) * Wait at least zfs_grow_retry (default 60) seconds * before considering growing. */ - growtime = ddi_get_lbolt() + (arc_grow_retry * hz); + growtime = gethrtime() + SEC2NSEC(arc_grow_retry); arc_kmem_reap_now(); @@ -3650,7 +3650,7 @@ arc_reclaim_thread(void *dummy __unused) } } else if (free_memory < arc_c >> arc_no_grow_shift) { arc_no_grow = B_TRUE; - } else if (ddi_get_lbolt() >= growtime) { + } else if (gethrtime() >= growtime) { arc_no_grow = B_FALSE; } @@ -3684,8 +3684,8 @@ arc_reclaim_thread(void *dummy __unused) * even if we aren't being signalled) */ CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait(&arc_reclaim_thread_cv, - &arc_reclaim_lock, hz); + (void) cv_timedwait_hires(&arc_reclaim_thread_cv, + &arc_reclaim_lock, SEC2NSEC(1), MSEC2NSEC(1), 0); CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_lock); } } @@ -4140,7 +4140,7 @@ arc_read_done(zio_t *zio) arc_cksum_compute(buf, B_FALSE); #ifdef illumos arc_buf_watch(buf); -#endif /* illumos */ +#endif if (hash_lock && zio->io_error == 0 && hdr->b_l1hdr.b_state == arc_anon) { @@ -4849,7 +4849,7 @@ arc_release(arc_buf_t *buf, void *tag) arc_cksum_verify(buf); #ifdef illumos arc_buf_unwatch(buf); -#endif /* illumos */ +#endif mutex_exit(hash_lock); @@ -5291,7 +5291,7 @@ arc_init(void) /* Start out with 1/8 of all memory */ arc_c = kmem_size() / 8; -#ifdef sun +#ifdef illumos #ifdef _KERNEL /* * On architectures where the physical memory can be larger @@ -5300,7 +5300,7 @@ arc_init(void) */ arc_c = MIN(arc_c, vmem_size(heap_arena, VMEM_ALLOC | VMEM_FREE) / 8); #endif -#endif /* sun */ +#endif /* illumos */ /* set min cache to 1/32 of all memory, or 16MB, whichever is more */ arc_c_min = MAX(arc_c / 4, 16 << 20); /* set max to 1/2 of all memory, or all but 1GB, whichever is more */ @@ -5570,10 +5570,12 @@ arc_fini(void) multilist_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA]); multilist_destroy(&arc_mfu->arcs_list[ARC_BUFC_METADATA]); multilist_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA]); + multilist_destroy(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA]); multilist_destroy(&arc_mru->arcs_list[ARC_BUFC_DATA]); multilist_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA]); multilist_destroy(&arc_mfu->arcs_list[ARC_BUFC_DATA]); multilist_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA]); + multilist_destroy(&arc_l2c_only->arcs_list[ARC_BUFC_DATA]); buf_fini(); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c index 7d20096..c706a38 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/bpobj.h> @@ -300,8 +301,10 @@ bpobj_iterate_impl(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx, if (free) { err = bpobj_space(&sublist, &used_before, &comp_before, &uncomp_before); - if (err) + if (err != 0) { + bpobj_close(&sublist); break; + } } err = bpobj_iterate_impl(&sublist, func, arg, tx, free); if (free) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c index b2b9887..a69fcc3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/arc.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c index f39a353..8b70cf5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c @@ -25,6 +25,7 @@ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 93a0426..6aa6327 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -1253,7 +1253,7 @@ dmu_write_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size, return (err); } -#ifdef sun +#ifdef illumos int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, page_t *pp, dmu_tx_t *tx) @@ -1309,7 +1309,7 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, return (err); } -#else +#else /* !illumos */ int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, @@ -1366,8 +1366,8 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_rele_array(dbp, numbufs, FTAG); return (err); } -#endif /* sun */ -#endif +#endif /* illumos */ +#endif /* _KERNEL */ /* * Allocate a loaned anonymous arc buffer. @@ -1421,6 +1421,9 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf, */ if (offset == db->db.db_offset && blksz == db->db.db_size && DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA) { +#ifdef _KERNEL + curthread->td_ru.ru_oublock++; +#endif dbuf_assign_arcbuf(db, buf, tx); dbuf_rele(db, FTAG); } else { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 79de1d1..367dbcb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -26,6 +26,7 @@ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2015, STRATO AG, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ @@ -1789,6 +1790,7 @@ dmu_objset_find_dp(dsl_pool_t *dp, uint64_t ddobj, * thread suffices. For now, stay single threaded. */ dmu_objset_find_dp_impl(dcp); + mutex_destroy(&err_lock); return (error); } @@ -1800,6 +1802,8 @@ dmu_objset_find_dp(dsl_pool_t *dp, uint64_t ddobj, INT_MAX, 0); if (tq == NULL) { kmem_free(dcp, sizeof (*dcp)); + mutex_destroy(&err_lock); + return (SET_ERROR(ENOMEM)); } dcp->dc_tq = tq; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c index ede1555..188810b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c @@ -25,6 +25,8 @@ * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright 2014 HybridCluster. All rights reserved. + * Copyright 2016 RackTop Systems. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dmu.h> @@ -64,6 +66,12 @@ int zfs_send_corrupt_data = B_FALSE; int zfs_send_queue_length = 16 * 1024 * 1024; int zfs_recv_queue_length = 16 * 1024 * 1024; +/* Set this tunable to FALSE to disable setting of DRR_FLAG_FREERECORDS */ +int zfs_send_set_freerecords_bit = B_TRUE; + +#ifdef _KERNEL +TUNABLE_INT("vfs.zfs.send_set_freerecords_bit", &zfs_send_set_freerecords_bit); +#endif static char *dmu_recv_tag = "dmu_recv_tag"; const char *recv_clone_name = "%recv"; @@ -158,6 +166,14 @@ dump_record(dmu_sendarg_t *dsp, void *payload, int payload_len) return (0); } +/* + * Fill in the drr_free struct, or perform aggregation if the previous record is + * also a free record, and the two are adjacent. + * + * Note that we send free records even for a full send, because we want to be + * able to receive a full send as a clone, which requires a list of all the free + * and freeobject records that were generated on the source. + */ static int dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset, uint64_t length) @@ -181,15 +197,6 @@ dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset, (object == dsp->dsa_last_data_object && offset > dsp->dsa_last_data_offset)); - /* - * If we are doing a non-incremental send, then there can't - * be any data in the dataset we're receiving into. Therefore - * a free record would simply be a no-op. Save space by not - * sending it to begin with. - */ - if (!dsp->dsa_incremental) - return (0); - if (length != -1ULL && offset + length < offset) length = -1ULL; @@ -368,10 +375,6 @@ dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs) { struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects); - /* See comment in dump_free(). */ - if (!dsp->dsa_incremental) - return (0); - /* * If there is a pending op, but it's not PENDING_FREEOBJECTS, * push it out, since free block aggregation can only be done for @@ -776,6 +779,8 @@ dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *to_ds, drr->drr_u.drr_begin.drr_toguid = dsl_dataset_phys(to_ds)->ds_guid; if (dsl_dataset_phys(to_ds)->ds_flags & DS_FLAG_CI_DATASET) drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CI_DATA; + if (zfs_send_set_freerecords_bit) + drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_FREERECORDS; if (ancestor_zb != NULL) { drr->drr_u.drr_begin.drr_fromguid = @@ -799,7 +804,6 @@ dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *to_ds, dsp->dsa_off = off; dsp->dsa_toguid = dsl_dataset_phys(to_ds)->ds_guid; dsp->dsa_pending_op = PENDING_NONE; - dsp->dsa_incremental = (ancestor_zb != NULL); dsp->dsa_featureflags = featureflags; dsp->dsa_resume_object = resumeobj; dsp->dsa_resume_offset = resumeoff; @@ -1321,7 +1325,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) /* target fs already exists; recv into temp clone */ /* Can't recv a clone into an existing fs */ - if (flags & DRR_FLAG_CLONE) { + if (flags & DRR_FLAG_CLONE || drba->drba_origin) { dsl_dataset_rele(ds, FTAG); return (SET_ERROR(EINVAL)); } @@ -1340,6 +1344,15 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) drba->drba_origin)) return (SET_ERROR(ENOENT)); + /* + * If we're receiving a full send as a clone, and it doesn't + * contain all the necessary free records and freeobject + * records, reject it. + */ + if (fromguid == 0 && drba->drba_origin && + !(flags & DRR_FLAG_FREERECORDS)) + return (SET_ERROR(EINVAL)); + /* Open the parent of tofs */ ASSERT3U(strlen(tofs), <, MAXNAMELEN); (void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1); @@ -1379,7 +1392,8 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) dsl_dataset_rele(ds, FTAG); return (SET_ERROR(EINVAL)); } - if (dsl_dataset_phys(origin)->ds_guid != fromguid) { + if (dsl_dataset_phys(origin)->ds_guid != fromguid && + fromguid != 0) { dsl_dataset_rele(origin, FTAG); dsl_dataset_rele(ds, FTAG); return (SET_ERROR(ENODEV)); @@ -1709,6 +1723,20 @@ struct receive_writer_arg { uint64_t bytes_read; /* bytes read when current record created */ }; +struct objlist { + list_t list; /* List of struct receive_objnode. */ + /* + * Last object looked up. Used to assert that objects are being looked + * up in ascending order. + */ + uint64_t last_lookup; +}; + +struct receive_objnode { + list_node_t node; + uint64_t object; +}; + struct receive_arg { objset_t *os; kthread_t *td; @@ -1727,12 +1755,7 @@ struct receive_arg { int err; boolean_t byteswap; /* Sorted list of objects not to issue prefetches for. */ - list_t ignore_obj_list; -}; - -struct receive_ign_obj_node { - list_node_t node; - uint64_t object; + struct objlist ignore_objlist; }; typedef struct guid_map_entry { @@ -2068,13 +2091,14 @@ receive_freeobjects(struct receive_writer_arg *rwa, struct drr_freeobjects *drrfo) { uint64_t obj; + int next_err = 0; if (drrfo->drr_firstobj + drrfo->drr_numobjs < drrfo->drr_firstobj) return (SET_ERROR(EINVAL)); for (obj = drrfo->drr_firstobj; - obj < drrfo->drr_firstobj + drrfo->drr_numobjs; - (void) dmu_object_next(rwa->os, &obj, FALSE, 0)) { + obj < drrfo->drr_firstobj + drrfo->drr_numobjs && next_err == 0; + next_err = dmu_object_next(rwa->os, &obj, FALSE, 0)) { int err; if (dmu_object_info(rwa->os, obj, NULL) != 0) @@ -2084,7 +2108,8 @@ receive_freeobjects(struct receive_writer_arg *rwa, if (err != 0) return (err); } - + if (next_err != ESRCH) + return (next_err); return (0); } @@ -2414,6 +2439,66 @@ receive_read_payload_and_next_header(struct receive_arg *ra, int len, void *buf) return (0); } +static void +objlist_create(struct objlist *list) +{ + list_create(&list->list, sizeof (struct receive_objnode), + offsetof(struct receive_objnode, node)); + list->last_lookup = 0; +} + +static void +objlist_destroy(struct objlist *list) +{ + for (struct receive_objnode *n = list_remove_head(&list->list); + n != NULL; n = list_remove_head(&list->list)) { + kmem_free(n, sizeof (*n)); + } + list_destroy(&list->list); +} + +/* + * This function looks through the objlist to see if the specified object number + * is contained in the objlist. In the process, it will remove all object + * numbers in the list that are smaller than the specified object number. Thus, + * any lookup of an object number smaller than a previously looked up object + * number will always return false; therefore, all lookups should be done in + * ascending order. + */ +static boolean_t +objlist_exists(struct objlist *list, uint64_t object) +{ + struct receive_objnode *node = list_head(&list->list); + ASSERT3U(object, >=, list->last_lookup); + list->last_lookup = object; + while (node != NULL && node->object < object) { + VERIFY3P(node, ==, list_remove_head(&list->list)); + kmem_free(node, sizeof (*node)); + node = list_head(&list->list); + } + return (node != NULL && node->object == object); +} + +/* + * The objlist is a list of object numbers stored in ascending order. However, + * the insertion of new object numbers does not seek out the correct location to + * store a new object number; instead, it appends it to the list for simplicity. + * Thus, any users must take care to only insert new object numbers in ascending + * order. + */ +static void +objlist_insert(struct objlist *list, uint64_t object) +{ + struct receive_objnode *node = kmem_zalloc(sizeof (*node), KM_SLEEP); + node->object = object; +#ifdef ZFS_DEBUG + struct receive_objnode *last_object = list_tail(&list->list); + uint64_t last_objnum = (last_object != NULL ? last_object->object : 0); + ASSERT3U(node->object, >, last_objnum); +#endif + list_insert_tail(&list->list, node); +} + /* * Issue the prefetch reads for any necessary indirect blocks. * @@ -2436,13 +2521,7 @@ static void receive_read_prefetch(struct receive_arg *ra, uint64_t object, uint64_t offset, uint64_t length) { - struct receive_ign_obj_node *node = list_head(&ra->ignore_obj_list); - while (node != NULL && node->object < object) { - VERIFY3P(node, ==, list_remove_head(&ra->ignore_obj_list)); - kmem_free(node, sizeof (*node)); - node = list_head(&ra->ignore_obj_list); - } - if (node == NULL || node->object > object) { + if (!objlist_exists(&ra->ignore_objlist, object)) { dmu_prefetch(ra->os, object, 1, offset, length, ZIO_PRIORITY_SYNC_READ); } @@ -2475,18 +2554,7 @@ receive_read_record(struct receive_arg *ra) */ if (err == ENOENT || (err == 0 && doi.doi_data_block_size != drro->drr_blksz)) { - struct receive_ign_obj_node *node = - kmem_zalloc(sizeof (*node), - KM_SLEEP); - node->object = drro->drr_object; -#ifdef ZFS_DEBUG - struct receive_ign_obj_node *last_object = - list_tail(&ra->ignore_obj_list); - uint64_t last_objnum = (last_object != NULL ? - last_object->object : 0); - ASSERT3U(node->object, >, last_objnum); -#endif - list_insert_tail(&ra->ignore_obj_list, node); + objlist_insert(&ra->ignore_objlist, drro->drr_object); err = 0; } return (err); @@ -2704,7 +2772,6 @@ resume_check(struct receive_arg *ra, nvlist_t *begin_nvl) return (0); } - /* * Read in the stream's records, one by one, and apply them to the pool. There * are two threads involved; the thread that calls this function will spin up a @@ -2739,8 +2806,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, struct file *fp, offset_t *voffp, sizeof (ra.bytes_read), 1, &ra.bytes_read); } - list_create(&ra.ignore_obj_list, sizeof (struct receive_ign_obj_node), - offsetof(struct receive_ign_obj_node, node)); + objlist_create(&ra.ignore_objlist); /* these were verified in dmu_recv_begin */ ASSERT3U(DMU_GET_STREAM_HDRTYPE(drc->drc_drrb->drr_versioninfo), ==, @@ -2894,12 +2960,7 @@ out: } *voffp = ra.voff; - for (struct receive_ign_obj_node *n = - list_remove_head(&ra.ignore_obj_list); n != NULL; - n = list_remove_head(&ra.ignore_obj_list)) { - kmem_free(n, sizeof (*n)); - } - list_destroy(&ra.ignore_obj_list); + objlist_destroy(&ra.ignore_objlist); return (err); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c index 65a017f..bea484f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dmu.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c index a295f90..39bef75 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -58,7 +59,7 @@ static dnode_phys_t dnode_phys_zero; int zfs_default_bs = SPA_MINBLOCKSHIFT; int zfs_default_ibs = DN_MAX_INDBLKSHIFT; -#ifdef sun +#ifdef illumos static kmem_cbrc_t dnode_move(void *, void *, size_t, void *); #endif @@ -840,7 +841,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) odn->dn_moved = (uint8_t)-1; } -#ifdef sun +#ifdef illumos #ifdef _KERNEL /*ARGSUSED*/ static kmem_cbrc_t @@ -983,7 +984,7 @@ dnode_move(void *buf, void *newbuf, size_t size, void *arg) return (KMEM_CBRC_YES); } #endif /* _KERNEL */ -#endif /* sun */ +#endif /* illumos */ void dnode_special_close(dnode_handle_t *dnh) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index 95e5392..00b9c7e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -25,6 +25,8 @@ * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2014 RackTop Systems. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved. */ #include <sys/dmu_objset.h> @@ -84,6 +86,8 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, max_recordsize, CTLFLAG_RWTUN, extern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds); +extern int spa_asize_inflation; + /* * Figure out how much of this delta should be propogated to the dsl_dir * layer. If there's a refreservation, that space has already been @@ -2896,6 +2900,11 @@ int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone, dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx) { + /* + * "slack" factor for received datasets with refquota set on them. + * See the bottom of this function for details on its use. + */ + uint64_t refquota_slack = DMU_MAX_ACCESS * spa_asize_inflation; int64_t unused_refres_delta; /* they should both be heads */ @@ -2938,10 +2947,22 @@ dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone, dsl_dir_space_available(origin_head->ds_dir, NULL, 0, TRUE)) return (SET_ERROR(ENOSPC)); - /* clone can't be over the head's refquota */ + /* + * The clone can't be too much over the head's refquota. + * + * To ensure that the entire refquota can be used, we allow one + * transaction to exceed the the refquota. Therefore, this check + * needs to also allow for the space referenced to be more than the + * refquota. The maximum amount of space that one transaction can use + * on disk is DMU_MAX_ACCESS * spa_asize_inflation. Allowing this + * overage ensures that we are able to receive a filesystem that + * exceeds the refquota on the source system. + * + * So that overage is the refquota_slack we use below. + */ if (origin_head->ds_quota != 0 && dsl_dataset_phys(clone)->ds_referenced_bytes > - origin_head->ds_quota) + origin_head->ds_quota + refquota_slack) return (SET_ERROR(EDQUOT)); return (0); @@ -2955,8 +2976,13 @@ dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone, int64_t unused_refres_delta; ASSERT(clone->ds_reserved == 0); + /* + * NOTE: On DEBUG kernels there could be a race between this and + * the check function if spa_asize_inflation is adjusted... + */ ASSERT(origin_head->ds_quota == 0 || - dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota); + dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota + + DMU_MAX_ACCESS * spa_asize_inflation); ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev); /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c index d26c6cd..7e3a122 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c @@ -22,6 +22,7 @@ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dsl_dataset.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c index 7de9845..b897176 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c @@ -23,6 +23,7 @@ * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2013 by Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c index 2bb74c8..d1b8002 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c @@ -23,6 +23,7 @@ * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/dsl_pool.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c index 3c6a29b..a157dfe 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright 2016 Gary Mills */ #include <sys/dsl_scan.h> @@ -855,7 +856,16 @@ dsl_scan_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx) if (scn->scn_phys.scn_bookmark.zb_objset == ds->ds_object) { if (ds->ds_is_snapshot) { - /* Note, scn_cur_{min,max}_txg stays the same. */ + /* + * Note: + * - scn_cur_{min,max}_txg stays the same. + * - Setting the flag is not really necessary if + * scn_cur_max_txg == scn_max_txg, because there + * is nothing after this snapshot that we care + * about. However, we set it anyway and then + * ignore it when we retraverse it in + * dsl_scan_visitds(). + */ scn->scn_phys.scn_bookmark.zb_objset = dsl_dataset_phys(ds)->ds_next_snap_obj; zfs_dbgmsg("destroying ds %llu; currently traversing; " @@ -895,9 +905,6 @@ dsl_scan_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx) zfs_dbgmsg("destroying ds %llu; in queue; removing", (u_longlong_t)ds->ds_object); } - } else { - zfs_dbgmsg("destroying ds %llu; ignoring", - (u_longlong_t)ds->ds_object); } /* @@ -1050,6 +1057,46 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx) VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds)); + if (scn->scn_phys.scn_cur_min_txg >= + scn->scn_phys.scn_max_txg) { + /* + * This can happen if this snapshot was created after the + * scan started, and we already completed a previous snapshot + * that was created after the scan started. This snapshot + * only references blocks with: + * + * birth < our ds_creation_txg + * cur_min_txg is no less than ds_creation_txg. + * We have already visited these blocks. + * or + * birth > scn_max_txg + * The scan requested not to visit these blocks. + * + * Subsequent snapshots (and clones) can reference our + * blocks, or blocks with even higher birth times. + * Therefore we do not need to visit them either, + * so we do not add them to the work queue. + * + * Note that checking for cur_min_txg >= cur_max_txg + * is not sufficient, because in that case we may need to + * visit subsequent snapshots. This happens when min_txg > 0, + * which raises cur_min_txg. In this case we will visit + * this dataset but skip all of its blocks, because the + * rootbp's birth time is < cur_min_txg. Then we will + * add the next snapshots/clones to the work queue. + */ + char *dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP); + dsl_dataset_name(ds, dsname); + zfs_dbgmsg("scanning dataset %llu (%s) is unnecessary because " + "cur_min_txg (%llu) >= max_txg (%llu)", + dsobj, dsname, + scn->scn_phys.scn_cur_min_txg, + scn->scn_phys.scn_max_txg); + kmem_free(dsname, MAXNAMELEN); + + goto out; + } + if (dmu_objset_from_ds(ds, &os)) goto out; @@ -1450,10 +1497,23 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) } /* + * Only process scans in sync pass 1. + */ + if (spa_sync_pass(dp->dp_spa) > 1) + return; + + /* + * If the spa is shutting down, then stop scanning. This will + * ensure that the scan does not dirty any new data during the + * shutdown phase. + */ + if (spa_shutting_down(spa)) + return; + + /* * If the scan is inactive due to a stalled async destroy, try again. */ - if ((!scn->scn_async_stalled && !dsl_scan_active(scn)) || - spa_sync_pass(dp->dp_spa) > 1) + if (!scn->scn_async_stalled && !dsl_scan_active(scn)) return; scn->scn_visited_this_txg = 0; @@ -1541,7 +1601,8 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) } if (err != 0) return; - if (!scn->scn_async_destroying && zfs_free_leak_on_eio && + if (dp->dp_free_dir != NULL && !scn->scn_async_destroying && + zfs_free_leak_on_eio && (dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes != 0 || dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes != 0 || dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes != 0)) { @@ -1567,7 +1628,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) -dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes, -dsl_dir_phys(dp->dp_free_dir)->dd_uncompressed_bytes, tx); } - if (!scn->scn_async_destroying) { + if (dp->dp_free_dir != NULL && !scn->scn_async_destroying) { /* finished; verify that space accounting went to zero */ ASSERT0(dsl_dir_phys(dp->dp_free_dir)->dd_used_bytes); ASSERT0(dsl_dir_phys(dp->dp_free_dir)->dd_compressed_bytes); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c index be0a688..0e75746 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c index 7e96e55..bae4a78 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c @@ -30,6 +30,11 @@ #ifdef _KERNEL int reference_tracking_enable = FALSE; /* runs out of memory too easily */ +SYSCTL_DECL(_vfs_zfs); +TUNABLE_INT("vfs.zfs.reference_tracking_enable", &reference_tracking_enable); +SYSCTL_INT(_vfs_zfs, OID_AUTO, reference_tracking_enable, CTLFLAG_RDTUN, + &reference_tracking_enable, 0, + "Track reference holders to refcount_t objects, used mostly by ZFS"); #else int reference_tracking_enable = TRUE; #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c index 90355a9..e11dd4d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c @@ -24,6 +24,7 @@ * Portions Copyright 2011 iXsystems, Inc * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -547,10 +548,9 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count, { int var_size = 0; int i; - int j = -1; int full_space; int hdrsize; - boolean_t done = B_FALSE; + int extra_hdrsize; if (buftype == SA_BONUS && sa->sa_force_spill) { *total = 0; @@ -561,10 +561,9 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count, *index = -1; *total = 0; + *will_spill = B_FALSE; - if (buftype == SA_BONUS) - *will_spill = B_FALSE; - + extra_hdrsize = 0; hdrsize = (SA_BONUSTYPE_FROM_DB(db) == DMU_OT_ZNODE) ? 0 : sizeof (sa_hdr_phys_t); @@ -576,8 +575,8 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count, *total = P2ROUNDUP(*total, 8); *total += attr_desc[i].sa_length; - if (done) - goto next; + if (*will_spill) + continue; is_var_sz = (SA_REGISTERED_LEN(sa, attr_desc[i].sa_attr) == 0); if (is_var_sz) { @@ -585,21 +584,28 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count, } if (is_var_sz && var_size > 1) { - if (P2ROUNDUP(hdrsize + sizeof (uint16_t), 8) + + /* + * Don't worry that the spill block might overflow. + * It will be resized if needed in sa_build_layouts(). + */ + if (buftype == SA_SPILL || + P2ROUNDUP(hdrsize + sizeof (uint16_t), 8) + *total < full_space) { /* * Account for header space used by array of * optional sizes of variable-length attributes. - * Record the index in case this increase needs - * to be reversed due to spill-over. + * Record the extra header size in case this + * increase needs to be reversed due to + * spill-over. */ hdrsize += sizeof (uint16_t); - j = i; + if (*index != -1) + extra_hdrsize += sizeof (uint16_t); } else { - done = B_TRUE; - *index = i; - if (buftype == SA_BONUS) - *will_spill = B_TRUE; + ASSERT(buftype == SA_BONUS); + if (*index == -1) + *index = i; + *will_spill = B_TRUE; continue; } } @@ -614,22 +620,15 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count, (*total + P2ROUNDUP(hdrsize, 8)) > (full_space - sizeof (blkptr_t))) { *index = i; - done = B_TRUE; } -next: if ((*total + P2ROUNDUP(hdrsize, 8)) > full_space && buftype == SA_BONUS) *will_spill = B_TRUE; } - /* - * j holds the index of the last variable-sized attribute for - * which hdrsize was increased. Reverse the increase if that - * attribute will be relocated to the spill block. - */ - if (*will_spill && j == *index) - hdrsize -= sizeof (uint16_t); + if (*will_spill) + hdrsize -= extra_hdrsize; hdrsize = P2ROUNDUP(hdrsize, 8); return (hdrsize); @@ -1654,7 +1653,7 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr, int spill_data_size = 0; int spill_attr_count = 0; int error; - uint16_t length; + uint16_t length, reg_length; int i, j, k, length_idx; sa_hdr_phys_t *hdr; sa_idx_tab_t *idx_tab; @@ -1714,34 +1713,50 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr, hdr = SA_GET_HDR(hdl, SA_BONUS); idx_tab = SA_IDX_TAB_GET(hdl, SA_BONUS); for (; k != 2; k++) { - /* iterate over each attribute in layout */ + /* + * Iterate over each attribute in layout. Fetch the + * size of variable-length attributes needing rewrite + * from sa_lengths[]. + */ for (i = 0, length_idx = 0; i != count; i++) { sa_attr_type_t attr; attr = idx_tab->sa_layout->lot_attrs[i]; - if (attr == newattr) { - /* duplicate attributes are not allowed */ - ASSERT(action == SA_REPLACE || - action == SA_REMOVE); - /* must be variable-sized to be replaced here */ - if (action == SA_REPLACE) { - ASSERT(SA_REGISTERED_LEN(sa, attr) == 0); - SA_ADD_BULK_ATTR(attr_desc, j, attr, - locator, datastart, buflen); - } + reg_length = SA_REGISTERED_LEN(sa, attr); + if (reg_length == 0) { + length = hdr->sa_lengths[length_idx]; + length_idx++; } else { - length = SA_REGISTERED_LEN(sa, attr); - if (length == 0) { - length = hdr->sa_lengths[length_idx]; - } + length = reg_length; + } + if (attr == newattr) { + /* + * There is nothing to do for SA_REMOVE, + * so it is just skipped. + */ + if (action == SA_REMOVE) + continue; + + /* + * Duplicate attributes are not allowed, so the + * action can not be SA_ADD here. + */ + ASSERT3S(action, ==, SA_REPLACE); + /* + * Only a variable-sized attribute can be + * replaced here, and its size must be changing. + */ + ASSERT3U(reg_length, ==, 0); + ASSERT3U(length, !=, buflen); + SA_ADD_BULK_ATTR(attr_desc, j, attr, + locator, datastart, buflen); + } else { SA_ADD_BULK_ATTR(attr_desc, j, attr, NULL, (void *) (TOC_OFF(idx_tab->sa_idx_tab[attr]) + (uintptr_t)old_data[k]), length); } - if (SA_REGISTERED_LEN(sa, attr) == 0) - length_idx++; } if (k == 0 && hdl->sa_spill) { hdr = SA_GET_HDR(hdl, SA_SPILL); @@ -1752,10 +1767,8 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr, } } if (action == SA_ADD) { - length = SA_REGISTERED_LEN(sa, newattr); - if (length == 0) { - length = buflen; - } + reg_length = SA_REGISTERED_LEN(sa, newattr); + IMPLY(reg_length != 0, reg_length == buflen); SA_ADD_BULK_ATTR(attr_desc, j, newattr, locator, datastart, buflen); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index 69b84b7..563967d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -21,11 +21,12 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* @@ -85,17 +86,21 @@ /* Check hostid on import? */ static int check_hostid = 1; -SYSCTL_DECL(_vfs_zfs); -TUNABLE_INT("vfs.zfs.check_hostid", &check_hostid); -SYSCTL_INT(_vfs_zfs, OID_AUTO, check_hostid, CTLFLAG_RW, &check_hostid, 0, - "Check hostid on import?"); - /* * The interval, in seconds, at which failed configuration cache file writes * should be retried. */ static int zfs_ccw_retry_interval = 300; +SYSCTL_DECL(_vfs_zfs); +TUNABLE_INT("vfs.zfs.check_hostid", &check_hostid); +SYSCTL_INT(_vfs_zfs, OID_AUTO, check_hostid, CTLFLAG_RWTUN, &check_hostid, 0, + "Check hostid on import?"); +TUNABLE_INT("vfs.zfs.ccw_retry_interval", &zfs_ccw_retry_interval); +SYSCTL_INT(_vfs_zfs, OID_AUTO, ccw_retry_interval, CTLFLAG_RW, + &zfs_ccw_retry_interval, 0, + "Configuration cache file write, retry after failure, interval (seconds)"); + typedef enum zti_modes { ZTI_MODE_FIXED, /* value is # of threads (min 1) */ ZTI_MODE_BATCH, /* cpu-intensive; value is ignored */ @@ -140,7 +145,7 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = { const zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = { /* ISSUE ISSUE_HIGH INTR INTR_HIGH */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* NULL */ - { ZTI_N(8), ZTI_NULL, ZTI_BATCH, ZTI_NULL }, /* READ */ + { ZTI_N(8), ZTI_NULL, ZTI_P(12, 8), ZTI_NULL }, /* READ */ { ZTI_BATCH, ZTI_N(5), ZTI_N(8), ZTI_N(5) }, /* WRITE */ { ZTI_P(12, 8), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* CLAIM */ @@ -3807,7 +3812,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, } #ifdef _KERNEL -#if defined(sun) +#ifdef illumos /* * Get the root pool information from the root disk, then import the root pool * during the system boot up time. @@ -4008,7 +4013,7 @@ out: return (error); } -#else +#else /* !illumos */ extern int vdev_geom_read_pool_label(const char *name, nvlist_t ***configs, uint64_t *count); @@ -4204,8 +4209,8 @@ spa_import_rootpool(const char *name) return (0); } -#endif /* sun */ -#endif +#endif /* illumos */ +#endif /* _KERNEL */ /* * Import a non-root pool into the system. @@ -5381,13 +5386,13 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config, spa_activate(newspa, spa_mode_global); spa_async_suspend(newspa); -#ifndef sun +#ifndef illumos /* mark that we are creating new spa by splitting */ newspa->spa_splitting_newspa = B_TRUE; #endif /* create the new pool from the disks of the original pool */ error = spa_load(newspa, SPA_LOAD_IMPORT, SPA_IMPORT_ASSEMBLE, B_TRUE); -#ifndef sun +#ifndef illumos newspa->spa_splitting_newspa = B_FALSE; #endif if (error) @@ -6343,8 +6348,7 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx) spa_config_exit(spa, SCL_STATE, FTAG); - if (spa->spa_config_syncing) - nvlist_free(spa->spa_config_syncing); + nvlist_free(spa->spa_config_syncing); spa->spa_config_syncing = config; spa_sync_nvlist(spa, spa->spa_config_object, config, tx); @@ -6644,12 +6648,12 @@ spa_sync(spa_t *spa, uint64_t txg) #ifdef illumos VERIFY(cyclic_reprogram(spa->spa_deadman_cycid, spa->spa_sync_starttime + spa->spa_deadman_synctime)); -#else /* FreeBSD */ +#else /* !illumos */ #ifdef _KERNEL callout_reset(&spa->spa_deadman_cycid, hz * spa->spa_deadman_synctime / NANOSEC, spa_deadman, spa); #endif -#endif +#endif /* illumos */ /* * If we are upgrading to SPA_VERSION_RAIDZ_DEFLATE this txg, @@ -6768,16 +6772,10 @@ spa_sync(spa_t *spa, uint64_t txg) if (svdcount == SPA_DVAS_PER_BP) break; } - error = vdev_config_sync(svd, svdcount, txg, B_FALSE); - if (error != 0) - error = vdev_config_sync(svd, svdcount, txg, - B_TRUE); + error = vdev_config_sync(svd, svdcount, txg); } else { error = vdev_config_sync(rvd->vdev_child, - rvd->vdev_children, txg, B_FALSE); - if (error != 0) - error = vdev_config_sync(rvd->vdev_child, - rvd->vdev_children, txg, B_TRUE); + rvd->vdev_children, txg); } if (error == 0) @@ -6794,11 +6792,11 @@ spa_sync(spa_t *spa, uint64_t txg) #ifdef illumos VERIFY(cyclic_reprogram(spa->spa_deadman_cycid, CY_INFINITY)); -#else /* FreeBSD */ +#else /* !illumos */ #ifdef _KERNEL callout_drain(&spa->spa_deadman_cycid); #endif -#endif +#endif /* illumos */ /* * Clear the dirty config list. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index be1e528..a5c17a5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -367,8 +367,7 @@ void spa_config_set(spa_t *spa, nvlist_t *config) { mutex_enter(&spa->spa_props_lock); - if (spa->spa_config != NULL) - nvlist_free(spa->spa_config); + nvlist_free(spa->spa_config); spa->spa_config = config; mutex_exit(&spa->spa_props_lock); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c index ecd5435..8965686 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/spa.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c index e18ffd2..49299b6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -21,10 +21,11 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -263,6 +264,33 @@ TUNABLE_INT("vfs.zfs.recover", &zfs_recover); SYSCTL_INT(_vfs_zfs, OID_AUTO, recover, CTLFLAG_RWTUN, &zfs_recover, 0, "Try to recover from otherwise-fatal errors."); +static int +sysctl_vfs_zfs_debug_flags(SYSCTL_HANDLER_ARGS) +{ + int err, val; + + val = zfs_flags; + err = sysctl_handle_int(oidp, &val, 0, req); + if (err != 0 || req->newptr == NULL) + return (err); + + /* + * ZFS_DEBUG_MODIFY must be enabled prior to boot so all + * arc buffers in the system have the necessary additional + * checksum data. However, it is safe to disable at any + * time. + */ + if (!(zfs_flags & ZFS_DEBUG_MODIFY)) + val &= ~ZFS_DEBUG_MODIFY; + zfs_flags = val; + + return (0); +} +TUNABLE_INT("vfs.zfs.debug_flags", &zfs_flags); +SYSCTL_PROC(_vfs_zfs, OID_AUTO, debug_flags, + CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(int), + sysctl_vfs_zfs_debug_flags, "IU", "Debug flags for ZFS testing."); + /* * If destroy encounters an EIO while reading metadata (e.g. indirect * blocks), space referenced by the missing metadata can not be freed. @@ -432,14 +460,16 @@ spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw) if (rw == RW_READER) { if (scl->scl_writer || scl->scl_write_wanted) { mutex_exit(&scl->scl_lock); - spa_config_exit(spa, locks ^ (1 << i), tag); + spa_config_exit(spa, locks & ((1 << i) - 1), + tag); return (0); } } else { ASSERT(scl->scl_writer != curthread); if (!refcount_is_zero(&scl->scl_count)) { mutex_exit(&scl->scl_lock); - spa_config_exit(spa, locks ^ (1 << i), tag); + spa_config_exit(spa, locks & ((1 << i) - 1), + tag); return (0); } scl->scl_writer = curthread; @@ -581,6 +611,12 @@ spa_deadman(void *arg) ++spa->spa_deadman_calls); if (zfs_deadman_enabled) vdev_deadman(spa->spa_root_vdev); +#ifdef __FreeBSD__ +#ifdef _KERNEL + callout_schedule(&spa->spa_deadman_cycid, + hz * zfs_deadman_checktime_ms / MILLISEC); +#endif +#endif } /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h index 6ba19c9..cb3b739 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h @@ -28,6 +28,7 @@ * Copyright 2014 HybridCluster. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ @@ -724,7 +725,7 @@ int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size, int dmu_write_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size, dmu_tx_t *tx); #ifdef _KERNEL -#ifdef sun +#ifdef illumos int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, struct page *pp, dmu_tx_t *tx); #else diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h index e8d6294..8cb6341 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h @@ -25,7 +25,7 @@ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>. All rights reserved. - * Copyright (c) 2013, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_DMU_IMPL_H @@ -296,7 +296,6 @@ typedef struct dmu_sendarg { uint64_t dsa_toguid; int dsa_err; dmu_pendop_t dsa_pending_op; - boolean_t dsa_incremental; uint64_t dsa_featureflags; uint64_t dsa_last_data_object; uint64_t dsa_last_data_offset; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h index 8a263a3..f05b2cf 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h @@ -23,6 +23,7 @@ * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h index 2865e82..19464a5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h @@ -24,6 +24,7 @@ * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _DMU_SEND_H diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h index d7df05b..766ae3c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h @@ -24,6 +24,7 @@ * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _SYS_DSL_DATASET_H diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h index be00621..105f889 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h @@ -24,6 +24,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _SYS_SPA_H @@ -625,7 +626,7 @@ extern int spa_get_stats(const char *pool, nvlist_t **config, char *altroot, size_t buflen); extern int spa_create(const char *pool, nvlist_t *config, nvlist_t *props, nvlist_t *zplprops); -#if defined(sun) +#ifdef illumos extern int spa_import_rootpool(char *devpath, char *devid); #else extern int spa_import_rootpool(const char *name); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h index 0f9a18b..a93ba83 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h @@ -256,7 +256,7 @@ struct spa { uint64_t spa_feat_refcount_cache[SPA_FEATURES]; #ifdef illumos cyclic_id_t spa_deadman_cycid; /* cyclic id */ -#else /* FreeBSD */ +#else /* !illumos */ #ifdef _KERNEL struct callout spa_deadman_cycid; /* callout id */ #endif @@ -286,7 +286,7 @@ struct spa { */ spa_config_lock_t spa_config_lock[SCL_LOCKS]; /* config changes */ refcount_t spa_refcount; /* number of opens */ -#ifndef sun +#ifndef illumos boolean_t spa_splitting_newspa; /* creating new spa in split */ #endif }; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h index ff46ba6..6312f03 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h @@ -127,8 +127,7 @@ extern void vdev_queue_register_lastoffset(vdev_t *vd, zio_t *zio); extern void vdev_config_dirty(vdev_t *vd); extern void vdev_config_clean(vdev_t *vd); -extern int vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, - boolean_t); +extern int vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg); extern void vdev_state_dirty(vdev_t *vd); extern void vdev_state_clean(vdev_t *vd); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h index a31d04c..77e291b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h @@ -60,7 +60,7 @@ typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size, uint64_t *logical_ashift, uint64_t *physical_ashift); typedef void vdev_close_func_t(vdev_t *vd); typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); -typedef int vdev_io_start_func_t(zio_t *zio); +typedef void vdev_io_start_func_t(zio_t *zio); typedef void vdev_io_done_func_t(zio_t *zio); typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef void vdev_hold_func_t(vdev_t *vd); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h index 09b052e..6af259f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _SYS_ZAP_IMPL_H diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h index 5102040..17503d8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h @@ -94,10 +94,8 @@ extern "C" { #include <sys/sunddi.h> #ifdef illumos #include <sys/cyclic.h> -#include <sys/callo.h> -#else /* FreeBSD */ -#include <sys/callout.h> #endif +#include <sys/callo.h> #include <sys/disp.h> #include <machine/stdarg.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h index 20bf545..f42df17 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h @@ -20,7 +20,9 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright 2016 RackTop Systems. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _SYS_ZFS_IOCTL_H @@ -124,8 +126,22 @@ typedef enum dmu_send_resume_token_version { #define DMU_BACKUP_MAGIC 0x2F5bacbacULL +/* + * Send stream flags. Bits 24-31 are reserved for vendor-specific + * implementations and should not be used. + */ #define DRR_FLAG_CLONE (1<<0) #define DRR_FLAG_CI_DATA (1<<1) +/* + * This send stream, if it is a full send, includes the FREE and FREEOBJECT + * records that are created by the sending process. This means that the send + * stream can be received as a clone, even though it is not an incremental. + * This is not implemented as a feature flag, because the receiving side does + * not need to have implemented it to receive this stream; it is fully backwards + * compatible. We need a flag, though, because full send streams without it + * cannot necessarily be received as a clone correctly. + */ +#define DRR_FLAG_FREERECORDS (1<<2) /* * flags in the drr_checksumflags field in the DRR_WRITE and @@ -298,6 +314,7 @@ typedef struct zinject_record { uint32_t zi_iotype; int32_t zi_duration; uint64_t zi_timer; + uint64_t zi_nlanes; uint32_t zi_cmd; uint32_t zi_pad; } zinject_record_t; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h index c8e3105..3e72ec4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #ifndef _SYS_FS_ZFS_ZNODE_H diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h index d3fe6e9..1642da0 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h index b5c666c..ac908bd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index 16d9ad2..56c821a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -150,9 +150,6 @@ enum zio_compress { #define ZIO_FAILURE_MODE_CONTINUE 1 #define ZIO_FAILURE_MODE_PANIC 2 -#define ZIO_PIPELINE_CONTINUE 0x100 -#define ZIO_PIPELINE_STOP 0x101 - enum zio_flag { /* * Flags inherited by gang, ddt, and vdev children, @@ -458,6 +455,7 @@ struct zio { uint64_t io_offset; hrtime_t io_timestamp; + hrtime_t io_target_timestamp; avl_node_t io_queue_node; avl_node_t io_offset_node; @@ -551,6 +549,8 @@ extern int zio_wait(zio_t *zio); extern void zio_nowait(zio_t *zio); extern void zio_execute(zio_t *zio); extern void zio_interrupt(zio_t *zio); +extern void zio_delay_init(zio_t *zio); +extern void zio_delay_interrupt(zio_t *zio); extern zio_t *zio_walk_parents(zio_t *cio); extern zio_t *zio_walk_children(zio_t *pio); @@ -612,7 +612,7 @@ extern int zio_handle_fault_injection(zio_t *zio, int error); extern int zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error); extern int zio_handle_label_injection(zio_t *zio, int error); extern void zio_handle_ignored_writes(zio_t *zio); -extern uint64_t zio_handle_io_delay(zio_t *zio); +extern hrtime_t zio_handle_io_delay(zio_t *zio); /* * Checksum ereport functions diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h index 75c6b37..7556eda 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h @@ -45,7 +45,7 @@ extern int zvol_remove_minor(const char *); extern void zvol_remove_minors(const char *); extern int zvol_set_volsize(const char *, uint64_t); -#ifdef sun +#ifdef illumos extern int zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr); extern int zvol_dump(dev_t dev, caddr_t addr, daddr_t offset, int nblocks); extern int zvol_close(dev_t dev, int flag, int otyp, cred_t *cr); @@ -54,14 +54,14 @@ extern int zvol_read(dev_t dev, uio_t *uiop, cred_t *cr); extern int zvol_write(dev_t dev, uio_t *uiop, cred_t *cr); extern int zvol_aread(dev_t dev, struct aio_req *aio, cred_t *cr); extern int zvol_awrite(dev_t dev, struct aio_req *aio, cred_t *cr); -#endif /* sun */ +#endif /* illumos */ extern int zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp); extern int zvol_busy(void); extern void zvol_init(void); extern void zvol_fini(void); -#ifdef sun +#ifdef illumos extern int zvol_get_volume_params(minor_t minor, uint64_t *blksize, uint64_t *max_xfer_len, void **minor_hdl, void **objset_hdl, void **zil_hdl, void **rl_hdl, void **bonus_hdl); @@ -69,7 +69,7 @@ extern uint64_t zvol_get_volume_size(void *minor_hdl); extern int zvol_get_volume_wce(void *minor_hdl); extern void zvol_log_write_minor(void *minor_hdl, dmu_tx_t *tx, offset_t off, ssize_t resid, boolean_t sync); -#endif /* sun */ +#endif /* illumos */ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) extern int zvol_create_minors(const char *name); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index a846487..28ff6c9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -24,6 +24,7 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -3401,7 +3402,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) boolean_t vdev_is_bootable(vdev_t *vd) { -#ifdef sun +#ifdef illumos if (!vd->vdev_ops->vdev_op_leaf) { char *vdev_type = vd->vdev_ops->vdev_op_type; @@ -3418,7 +3419,7 @@ vdev_is_bootable(vdev_t *vd) if (!vdev_is_bootable(vd->vdev_child[c])) return (B_FALSE); } -#endif /* sun */ +#endif /* illumos */ return (B_TRUE); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c index eaa9dfc..681a670 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ @@ -691,7 +691,7 @@ vdev_disk_io_intr(buf_t *bp) kmem_free(vb, sizeof (vdev_buf_t)); - zio_interrupt(zio); + zio_delay_interrupt(zio); } static void @@ -715,7 +715,7 @@ vdev_disk_ioctl_done(void *zio_arg, int error) zio_interrupt(zio); } -static int +static void vdev_disk_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -732,7 +732,7 @@ vdev_disk_io_start(zio_t *zio) if (dvd == NULL || (dvd->vd_ldi_offline && dvd->vd_lh == NULL)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } if (zio->io_type == ZIO_TYPE_IOCTL) { @@ -740,7 +740,7 @@ vdev_disk_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } switch (zio->io_cmd) { @@ -771,7 +771,7 @@ vdev_disk_io_start(zio_t *zio) * and will call vdev_disk_ioctl_done() * upon completion. */ - return (ZIO_PIPELINE_STOP); + return; } if (error == ENOTSUP || error == ENOTTY) { @@ -792,11 +792,12 @@ vdev_disk_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + zio->io_target_timestamp = zio_handle_io_delay(zio); vb = kmem_alloc(sizeof (vdev_buf_t), KM_SLEEP); @@ -816,8 +817,6 @@ vdev_disk_io_start(zio_t *zio) /* ldi_strategy() will return non-zero only on programming errors */ VERIFY(ldi_strategy(dvd->vd_lh, bp) == 0); - - return (ZIO_PIPELINE_STOP); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c index ad21d6e..8228af1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. */ #include <sys/zfs_context.h> @@ -156,7 +156,7 @@ vdev_file_close(vdev_t *vd) vd->vdev_tsd = NULL; } -static int +static void vdev_file_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -167,7 +167,7 @@ vdev_file_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } vf = vd->vdev_tsd; @@ -183,11 +183,12 @@ vdev_file_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + zio->io_target_timestamp = zio_handle_io_delay(zio); zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ? UIO_READ : UIO_WRITE, vp, zio->io_data, zio->io_size, @@ -196,9 +197,12 @@ vdev_file_io_start(zio_t *zio) if (resid != 0 && zio->io_error == 0) zio->io_error = ENOSPC; - zio_interrupt(zio); + zio_delay_interrupt(zio); - return (ZIO_PIPELINE_STOP); +#ifdef illumos + VERIFY3U(taskq_dispatch(system_taskq, vdev_file_io_strategy, bp, + TQ_SLEEP), !=, 0); +#endif } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index 763ea1a..d64001e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -80,6 +80,9 @@ static void vdev_geom_attrchanged(struct g_consumer *cp, const char *attr) { vdev_t *vd; + spa_t *spa; + char *physpath; + int error, physpath_len; vd = cp->private; if (vd == NULL) @@ -89,6 +92,47 @@ vdev_geom_attrchanged(struct g_consumer *cp, const char *attr) vdev_geom_set_rotation_rate(vd, cp); return; } + + if (strcmp(attr, "GEOM::physpath") != 0) + return; + + if (g_access(cp, 1, 0, 0) != 0) + return; + + /* + * Record/Update physical path information for this device. + */ + spa = vd->vdev_spa; + physpath_len = MAXPATHLEN; + physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO); + error = g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath); + g_access(cp, -1, 0, 0); + if (error == 0) { + char *old_physpath; + + old_physpath = vd->vdev_physpath; + vd->vdev_physpath = spa_strdup(physpath); + spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE); + + if (old_physpath != NULL) { + int held_lock; + + held_lock = spa_config_held(spa, SCL_STATE, RW_WRITER); + if (held_lock == 0) { + g_topology_unlock(); + spa_config_enter(spa, SCL_STATE, FTAG, + RW_WRITER); + } + + spa_strfree(old_physpath); + + if (held_lock == 0) { + spa_config_exit(spa, SCL_STATE, FTAG); + g_topology_lock(); + } + } + } + g_free(physpath); } static void @@ -99,8 +143,10 @@ vdev_geom_orphan(struct g_consumer *cp) g_topology_assert(); vd = cp->private; - if (vd == NULL) + if (vd == NULL) { + /* Vdev close in progress. Ignore the event. */ return; + } /* * Orphan callbacks occur from the GEOM event thread. @@ -121,7 +167,7 @@ vdev_geom_orphan(struct g_consumer *cp) } static struct g_consumer * -vdev_geom_attach(struct g_provider *pp) +vdev_geom_attach(struct g_provider *pp, vdev_t *vd) { struct g_geom *gp; struct g_consumer *cp; @@ -140,6 +186,7 @@ vdev_geom_attach(struct g_provider *pp) if (gp == NULL) { gp = g_new_geomf(&zfs_vdev_class, "zfs::vdev"); gp->orphan = vdev_geom_orphan; + gp->attrchanged = vdev_geom_attrchanged; cp = g_new_consumer(gp); if (g_attach(cp, pp) != 0) { g_wither_geom(gp, ENXIO); @@ -176,28 +223,56 @@ vdev_geom_attach(struct g_provider *pp) ZFS_LOG(1, "Used existing consumer for %s.", pp->name); } } + + /* + * BUG: cp may already belong to a vdev. This could happen if: + * 1) That vdev is a shared spare, or + * 2) We are trying to reopen a missing vdev and we are scanning by + * guid. In that case, we'll ultimately fail to open this consumer, + * but not until after setting the private field. + * The solution is to: + * 1) Don't set the private field until after the open succeeds, and + * 2) Set it to a linked list of vdevs, not just a single vdev + */ + cp->private = vd; + vd->vdev_tsd = cp; + + /* Fetch initial physical path information for this device. */ + vdev_geom_attrchanged(cp, "GEOM::physpath"); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; return (cp); } static void -vdev_geom_detach(void *arg, int flag __unused) +vdev_geom_close_locked(vdev_t *vd) { struct g_geom *gp; struct g_consumer *cp; g_topology_assert(); - cp = arg; - gp = cp->geom; + + cp = vd->vdev_tsd; + if (cp == NULL) + return; ZFS_LOG(1, "Closing access to %s.", cp->provider->name); + KASSERT(vd->vdev_tsd == cp, ("%s: vdev_tsd is not cp", __func__)); + vd->vdev_tsd = NULL; + vd->vdev_delayed_close = B_FALSE; + cp->private = NULL; + + gp = cp->geom; g_access(cp, -1, 0, -1); /* Destroy consumer on last close. */ if (cp->acr == 0 && cp->ace == 0) { - ZFS_LOG(1, "Destroyed consumer to %s.", cp->provider->name); if (cp->acw > 0) g_access(cp, 0, -cp->acw, 0); - g_detach(cp); + if (cp->provider != NULL) { + ZFS_LOG(1, "Destroyed consumer to %s.", + cp->provider->name); + g_detach(cp); + } g_destroy_consumer(cp); } /* Destroy geom if there are no consumers left. */ @@ -491,7 +566,7 @@ vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid) } static struct g_consumer * -vdev_geom_attach_by_guids(uint64_t pool_guid, uint64_t vdev_guid) +vdev_geom_attach_by_guids(vdev_t *vd) { struct g_class *mp; struct g_geom *gp, *zgp; @@ -528,10 +603,10 @@ vdev_geom_attach_by_guids(uint64_t pool_guid, uint64_t vdev_guid) * label.) */ if ((pguid != 0 && - pguid != pool_guid) || - vguid != vdev_guid) + pguid != spa_guid(vd->vdev_spa)) || + vguid != vd->vdev_guid) continue; - cp = vdev_geom_attach(pp); + cp = vdev_geom_attach(pp, vd); if (cp == NULL) { printf("ZFS WARNING: Unable to " "attach to %s.\n", pp->name); @@ -561,7 +636,7 @@ vdev_geom_open_by_guids(vdev_t *vd) g_topology_assert(); ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid); - cp = vdev_geom_attach_by_guids(spa_guid(vd->vdev_spa), vd->vdev_guid); + cp = vdev_geom_attach_by_guids(vd); if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); @@ -595,7 +670,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1); if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); - cp = vdev_geom_attach(pp); + cp = vdev_geom_attach(pp, vd); if (cp != NULL && check_guid && ISP2(pp->sectorsize) && pp->sectorsize <= VDEV_PAD_SIZE) { g_topology_unlock(); @@ -603,7 +678,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) g_topology_lock(); if (pguid != spa_guid(vd->vdev_spa) || vguid != vd->vdev_guid) { - vdev_geom_detach(cp, 0); + vdev_geom_close_locked(vd); cp = NULL; ZFS_LOG(1, "guid mismatch for provider %s: " "%ju:%ju != %ju:%ju.", vd->vdev_path, @@ -685,7 +760,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, !ISP2(cp->provider->sectorsize)) { ZFS_LOG(1, "Provider %s has unsupported sectorsize.", vd->vdev_path); - vdev_geom_detach(cp, 0); + + vdev_geom_close_locked(vd); error = EINVAL; cp = NULL; } else if (cp->acw == 0 && (spa_mode(vd->vdev_spa) & FWRITE) != 0) { @@ -702,19 +778,17 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, if (error != 0) { printf("ZFS WARNING: Unable to open %s for writing (error=%d).\n", vd->vdev_path, error); - vdev_geom_detach(cp, 0); + vdev_geom_close_locked(vd); cp = NULL; } } + g_topology_unlock(); PICKUP_GIANT(); if (cp == NULL) { vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; return (error); } - - cp->private = vd; - vd->vdev_tsd = cp; pp = cp->provider; /* @@ -728,7 +802,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, */ *logical_ashift = highbit(MAX(pp->sectorsize, SPA_MINBLOCKSIZE)) - 1; *physical_ashift = 0; - if (pp->stripesize) + if (pp->stripesize > (1 << *logical_ashift) && ISP2(pp->stripesize) && + pp->stripesize <= (1 << SPA_MAXASHIFT) && pp->stripeoffset == 0) *physical_ashift = highbit(pp->stripesize) - 1; /* @@ -737,12 +812,6 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, */ vd->vdev_nowritecache = B_FALSE; - if (vd->vdev_physpath != NULL) - spa_strfree(vd->vdev_physpath); - bufsize = sizeof("/dev/") + strlen(pp->name); - vd->vdev_physpath = kmem_alloc(bufsize, KM_SLEEP); - snprintf(vd->vdev_physpath, bufsize, "/dev/%s", pp->name); - /* * Determine the device's rotation rate. */ @@ -754,15 +823,12 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, static void vdev_geom_close(vdev_t *vd) { - struct g_consumer *cp; - cp = vd->vdev_tsd; - if (cp == NULL) - return; - vd->vdev_tsd = NULL; - vd->vdev_delayed_close = B_FALSE; - cp->private = NULL; /* XXX locking */ - g_post_event(vdev_geom_detach, cp, M_WAITOK, NULL); + DROP_GIANT(); + g_topology_lock(); + vdev_geom_close_locked(vd); + g_topology_unlock(); + PICKUP_GIANT(); } static void @@ -811,10 +877,10 @@ vdev_geom_io_intr(struct bio *bp) break; } g_destroy_bio(bp); - zio_interrupt(zio); + zio_delay_interrupt(zio); } -static int +static void vdev_geom_io_start(zio_t *zio) { vdev_t *vd; @@ -829,6 +895,8 @@ vdev_geom_io_start(zio_t *zio) /* XXPOLICY */ if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); + zio_interrupt(zio); + return; } else { switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: @@ -844,16 +912,16 @@ vdev_geom_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; case ZIO_TYPE_FREE: if (vd->vdev_notrim) { zio->io_error = SET_ERROR(ENOTSUP); } else if (!vdev_geom_bio_delete_disable) { goto sendreq; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } sendreq: ASSERT(zio->io_type == ZIO_TYPE_READ || @@ -865,13 +933,14 @@ sendreq: if (cp == NULL) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } bp = g_alloc_bio(); bp->bio_caller1 = zio; switch (zio->io_type) { case ZIO_TYPE_READ: case ZIO_TYPE_WRITE: + zio->io_target_timestamp = zio_handle_io_delay(zio); bp->bio_cmd = zio->io_type == ZIO_TYPE_READ ? BIO_READ : BIO_WRITE; bp->bio_data = zio->io_data; bp->bio_offset = zio->io_offset; @@ -894,8 +963,6 @@ sendreq: bp->bio_done = vdev_geom_io_intr; g_io_request(bp, cp); - - return (ZIO_PIPELINE_STOP); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c index 9befa75..77191e7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c @@ -602,7 +602,8 @@ vdev_inuse(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason, * read-only. Instead we look to see if the pools is marked * read-only in the namespace and set the state to active. */ - if ((spa = spa_by_guid(pool_guid, device_guid)) != NULL && + if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE && + (spa = spa_by_guid(pool_guid, device_guid)) != NULL && spa_mode(spa) == FREAD) state = POOL_STATE_ACTIVE; @@ -1193,15 +1194,16 @@ vdev_label_sync_list(spa_t *spa, int l, uint64_t txg, int flags) * at any time, you can just call it again, and it will resume its work. */ int -vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard) +vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg) { spa_t *spa = svd[0]->vdev_spa; uberblock_t *ub = &spa->spa_uberblock; vdev_t *vd; zio_t *zio; - int error; + int error = 0; int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; +retry: /* * Normally, we don't want to try too hard to write every label and * uberblock. If there is a flaky disk, we don't want the rest of the @@ -1209,8 +1211,11 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard) * single label out, we should retry with ZIO_FLAG_TRYHARD before * bailing out and declaring the pool faulted. */ - if (tryhard) + if (error != 0) { + if ((flags & ZIO_FLAG_TRYHARD) != 0) + return (error); flags |= ZIO_FLAG_TRYHARD; + } ASSERT(ub->ub_txg <= txg); @@ -1254,7 +1259,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard) * are committed to stable storage before the uberblock update. */ if ((error = vdev_label_sync_list(spa, 0, txg, flags)) != 0) - return (error); + goto retry; /* * Sync the uberblocks to all vdevs in svd[]. @@ -1272,7 +1277,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard) * to the new uberblocks. */ if ((error = vdev_uberblock_sync_list(svd, svdcount, ub, flags)) != 0) - return (error); + goto retry; /* * Sync out odd labels for every dirty vdev. If the system dies @@ -1285,7 +1290,7 @@ vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg, boolean_t tryhard) * stable storage before the next transaction group begins. */ if ((error = vdev_label_sync_list(spa, 1, txg, flags)) != 0) - return (error); + goto retry;; trim_thread_wakeup(spa); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c index 9d22d1e..65acd47 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ #include <sys/zfs_context.h> @@ -431,7 +431,7 @@ vdev_mirror_child_select(zio_t *zio) return (-1); } -static int +static void vdev_mirror_io_start(zio_t *zio) { mirror_map_t *mm; @@ -457,8 +457,8 @@ vdev_mirror_io_start(zio_t *zio) zio->io_type, zio->io_priority, 0, vdev_mirror_scrub_done, mc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } /* * For normal reads just pick one child. @@ -485,8 +485,7 @@ vdev_mirror_io_start(zio_t *zio) c++; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c index fec0037..24a44a6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ /* @@ -67,12 +67,11 @@ vdev_missing_close(vdev_t *vd) } /* ARGSUSED */ -static int +static void vdev_missing_io_start(zio_t *zio) { zio->io_error = SET_ERROR(ENOTSUP); - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c index 9f83abb..a1d1d79 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c @@ -25,6 +25,7 @@ /* * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -883,9 +884,6 @@ vdev_queue_io_done(zio_t *zio) vdev_queue_t *vq = &zio->io_vd->vdev_queue; zio_t *nio; - if (zio_injection_enabled) - delay(SEC_TO_TICK(zio_handle_io_delay(zio))); - mutex_enter(&vq->vq_lock); vdev_queue_pending_remove(vq, zio); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c index 33bedc1..a755f3a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c @@ -21,8 +21,9 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zfs_context.h> @@ -1726,7 +1727,7 @@ vdev_raidz_child_done(zio_t *zio) * vdevs have had errors, then create zio read operations to the parity * columns' VDevs as well. */ -static int +static void vdev_raidz_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -1756,8 +1757,8 @@ vdev_raidz_io_start(zio_t *zio) vdev_raidz_child_done, rc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } if (zio->io_type == ZIO_TYPE_WRITE) { @@ -1789,8 +1790,8 @@ vdev_raidz_io_start(zio_t *zio) ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -1830,8 +1831,7 @@ vdev_raidz_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c index 8ca68b8..ea3d869 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/zio.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c index 6545dc2..fd1d59b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c @@ -1994,8 +1994,8 @@ top: zfs_sa_upgrade_txholds(tx, zp); error = dmu_tx_assign(tx, TXG_NOWAIT); if (error) { - mutex_exit(&zp->z_acl_lock); mutex_exit(&zp->z_lock); + mutex_exit(&zp->z_acl_lock); if (error == ERESTART) { dmu_tx_wait(tx); @@ -2020,7 +2020,6 @@ top: if (fuidp) zfs_fuid_info_free(fuidp); dmu_tx_commit(tx); -done: mutex_exit(&zp->z_lock); mutex_exit(&zp->z_acl_lock); @@ -2053,7 +2052,7 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) return (SET_ERROR(EPERM)); } -#ifdef sun +#ifdef illumos if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) && (zp->z_pflags & ZFS_NOUNLINK)) { return (SET_ERROR(EPERM)); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c index 22bbfb2..693ba41 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c @@ -113,7 +113,7 @@ snapentry_compare(const void *a, const void *b) return (0); } -#ifdef sun +#ifdef illumos vnodeops_t *zfsctl_ops_root; vnodeops_t *zfsctl_ops_snapdir; vnodeops_t *zfsctl_ops_snapshot; @@ -124,20 +124,20 @@ static const fs_operation_def_t zfsctl_tops_root[]; static const fs_operation_def_t zfsctl_tops_snapdir[]; static const fs_operation_def_t zfsctl_tops_snapshot[]; static const fs_operation_def_t zfsctl_tops_shares[]; -#else /* !sun */ +#else static struct vop_vector zfsctl_ops_root; static struct vop_vector zfsctl_ops_snapdir; static struct vop_vector zfsctl_ops_snapshot; static struct vop_vector zfsctl_ops_shares; static struct vop_vector zfsctl_ops_shares_dir; -#endif /* !sun */ +#endif static vnode_t *zfsctl_mknode_snapdir(vnode_t *); static vnode_t *zfsctl_mknode_shares(vnode_t *); static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset); static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *); -#ifdef sun +#ifdef illumos static gfs_opsvec_t zfsctl_opsvec[] = { { ".zfs", zfsctl_tops_root, &zfsctl_ops_root }, { ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir }, @@ -146,7 +146,7 @@ static gfs_opsvec_t zfsctl_opsvec[] = { { ".zfs/shares/vnode", zfsctl_tops_shares, &zfsctl_ops_shares }, { NULL } }; -#endif /* sun */ +#endif /* * Root directory elements. We only have two entries @@ -171,7 +171,7 @@ static gfs_dirent_t zfsctl_root_entries[] = { void zfsctl_init(void) { -#ifdef sun +#ifdef illumos VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0); #endif } @@ -179,7 +179,7 @@ zfsctl_init(void) void zfsctl_fini(void) { -#ifdef sun +#ifdef illumos /* * Remove vfsctl vnode ops */ @@ -199,7 +199,7 @@ zfsctl_fini(void) zfsctl_ops_snapshot = NULL; zfsctl_ops_shares = NULL; zfsctl_ops_shares_dir = NULL; -#endif /* sun */ +#endif /* illumos */ } boolean_t @@ -550,7 +550,7 @@ zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, return (err); } -#ifdef sun +#ifdef illumos static int zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, caller_context_t *ct) @@ -566,9 +566,9 @@ zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, return (fs_pathconf(vp, cmd, valp, cr, ct)); } -#endif /* sun */ +#endif /* illumos */ -#ifdef sun +#ifdef illumos static const fs_operation_def_t zfsctl_tops_root[] = { { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, @@ -583,7 +583,7 @@ static const fs_operation_def_t zfsctl_tops_root[] = { { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, { NULL } }; -#endif /* sun */ +#endif /* illumos */ /* * Special case the handling of "..". @@ -677,7 +677,7 @@ zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr) if ((error = vn_vfswlock(svp)) != 0) return (error); -#ifdef sun +#ifdef illumos VN_HOLD(svp); error = dounmount(vn_mountedvfs(svp), fflags, cr); if (error) { @@ -697,13 +697,13 @@ zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr) kmem_free(sep, sizeof (zfs_snapentry_t)); return (0); -#else /* !sun */ +#else vfs_ref(vn_mountedvfs(svp)); return (dounmount(vn_mountedvfs(svp), fflags, curthread)); -#endif /* !sun */ +#endif } -#ifdef sun +#ifdef illumos static void zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) { @@ -756,9 +756,9 @@ zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) vfs_unlock(vfsp); } -#endif /* sun */ +#endif /* illumos */ -#ifdef sun +#ifdef illumos /*ARGSUSED*/ static int zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, @@ -823,9 +823,9 @@ zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, return (err); } -#endif /* sun */ +#endif /* illumos */ -#ifdef sun +#ifdef illumos /* ARGSUSED */ static int zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, @@ -881,7 +881,7 @@ zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, return (err); } -#endif /* sun */ +#endif /* illumos */ /* * This creates a snapshot under '.zfs/snapshot'. @@ -1069,7 +1069,7 @@ zfsctl_snapdir_lookup(ap) } ZFS_EXIT(zfsvfs); return (err); -#endif /* !illumos */ +#endif /* illumos */ } sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP); @@ -1377,7 +1377,7 @@ zfsctl_snapdir_inactive(ap) return (0); } -#ifdef sun +#ifdef illumos static const fs_operation_def_t zfsctl_tops_snapdir[] = { { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, @@ -1408,7 +1408,7 @@ static const fs_operation_def_t zfsctl_tops_shares[] = { { VOPNAME_FID, { .vop_fid = zfsctl_shares_fid } }, { NULL } }; -#else /* !sun */ +#else /* !illumos */ static struct vop_vector zfsctl_ops_snapdir = { .vop_default = &default_vnodeops, .vop_open = zfsctl_common_open, @@ -1437,7 +1437,7 @@ static struct vop_vector zfsctl_ops_shares = { .vop_reclaim = gfs_vop_reclaim, .vop_fid = zfsctl_shares_fid, }; -#endif /* !sun */ +#endif /* illumos */ /* * pvp is the GFS vnode '.zfs/snapshot'. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c index e2a3bff..cf42ff6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c @@ -222,7 +222,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, mutex_enter(&dzp->z_lock); for (;;) { - if (dzp->z_unlinked) { + if (dzp->z_unlinked && !(flag & ZXATTR)) { mutex_exit(&dzp->z_lock); if (!(flag & ZHAVELOCK)) rw_exit(&dzp->z_name_lock); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c index 197e122..e74799a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c @@ -406,7 +406,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, domain = zfs_fuid_find_by_idx(zfsvfs, index); ASSERT(domain != NULL); -#ifdef sun +#ifdef illumos if (type == ZFS_OWNER || type == ZFS_ACE_USER) { (void) kidmap_getuidbysid(crgetzone(cr), domain, FUID_RID(fuid), &id); @@ -414,9 +414,9 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, (void) kidmap_getgidbysid(crgetzone(cr), domain, FUID_RID(fuid), &id); } -#else /* !sun */ +#else id = UID_NOBODY; -#endif /* !sun */ +#endif return (id); } @@ -703,13 +703,13 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp) boolean_t zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) { -#ifdef sun +#ifdef illumos ksid_t *ksid = crgetsid(cr, KSID_GROUP); ksidlist_t *ksidlist = crgetsidlist(cr); -#endif /* !sun */ +#endif uid_t gid; -#ifdef sun +#ifdef illumos if (ksid && ksidlist) { int i; ksid_t *ksid_groups; @@ -741,7 +741,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) } } } -#endif /* !sun */ +#endif /* illumos */ /* * Not found in ksidlist, check posix groups diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 6d9877b..8483fd7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -25,11 +25,13 @@ * All rights reserved. * Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. * Copyright 2014 Xin Li <delphij@FreeBSD.org>. All rights reserved. + * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* @@ -132,6 +134,9 @@ * distinguish between the operation failing, and * deserialization failing. */ +#ifdef __FreeBSD__ +#include "opt_kstack_pages.h" +#endif #include <sys/types.h> #include <sys/param.h> @@ -1335,7 +1340,7 @@ get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp) if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size, iflag)) != 0) { kmem_free(packed, size); - return (error); + return (SET_ERROR(EFAULT)); } if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) { @@ -1596,8 +1601,7 @@ zfs_ioc_pool_import(zfs_cmd_t *zc) nvlist_free(config); - if (props) - nvlist_free(props); + nvlist_free(props); return (error); } @@ -3745,10 +3749,12 @@ static int zfs_ioc_rename(zfs_cmd_t *zc) { boolean_t recursive = zc->zc_cookie & 1; + char *at; + boolean_t allow_mounted = B_TRUE; + #ifdef __FreeBSD__ - boolean_t allow_mounted = zc->zc_cookie & 2; + allow_mounted = (zc->zc_cookie & 2) != 0; #endif - char *at; zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || @@ -3763,11 +3769,7 @@ zfs_ioc_rename(zfs_cmd_t *zc) if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1)) return (SET_ERROR(EXDEV)); *at = '\0'; -#ifdef illumos - if (zc->zc_objset_type == DMU_OST_ZFS) { -#else if (zc->zc_objset_type == DMU_OST_ZFS && allow_mounted) { -#endif error = dmu_objset_find(zc->zc_name, recursive_unmount, at + 1, recursive ? DS_FIND_CHILDREN : 0); @@ -3969,7 +3971,7 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr) return (SET_ERROR(EINVAL)); /* check prop value is enabled in features */ - feature = zio_checksum_to_feature(intval); + feature = zio_checksum_to_feature(intval & ZIO_CHECKSUM_MASK); if (feature == SPA_FEATURE_NONE) break; @@ -4175,6 +4177,56 @@ next: } } +/* + * 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. + */ +static nvlist_t * +extract_delay_props(nvlist_t *props) +{ + nvlist_t *delayprops; + nvpair_t *nvp, *tmp; + static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 }; + int i; + + VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0); + + for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL; + nvp = nvlist_next_nvpair(props, nvp)) { + /* + * strcmp() is safe because zfs_prop_to_name() always returns + * a bounded string. + */ + for (i = 0; delayable[i] != 0; i++) { + if (strcmp(zfs_prop_to_name(delayable[i]), + nvpair_name(nvp)) == 0) { + break; + } + } + if (delayable[i] != 0) { + tmp = nvlist_prev_nvpair(props, nvp); + VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0); + VERIFY(nvlist_remove_nvpair(props, nvp) == 0); + nvp = tmp; + } + } + + if (nvlist_empty(delayprops)) { + nvlist_free(delayprops); + delayprops = NULL; + } + return (delayprops); +} + #ifdef DEBUG static boolean_t zfs_ioc_recv_inject_err; #endif @@ -4211,6 +4263,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) offset_t off; nvlist_t *props = NULL; /* sent properties */ nvlist_t *origprops = NULL; /* existing properties */ + nvlist_t *delayprops = NULL; /* sent properties applied post-receive */ char *origin = NULL; char *tosnap; char tofs[ZFS_MAXNAMELEN]; @@ -4296,21 +4349,12 @@ zfs_ioc_recv(zfs_cmd_t *zc) props_error = dsl_prop_set_hasrecvd(tofs); if (props_error == 0) { + delayprops = extract_delay_props(props); (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED, props, errors); } } - if (zc->zc_nvlist_dst_size != 0 && - (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 || - put_nvlist(zc, errors) != 0)) { - /* - * Caller made zc->zc_nvlist_dst less than the minimum expected - * size or supplied an invalid address. - */ - props_error = SET_ERROR(EINVAL); - } - off = fp->f_offset; error = dmu_recv_stream(&drc, fp, &off, zc->zc_cleanup_fd, &zc->zc_action_handle); @@ -4335,6 +4379,40 @@ zfs_ioc_recv(zfs_cmd_t *zc) } else { error = dmu_recv_end(&drc, NULL); } + + /* Set delayed properties now, after we're done receiving. */ + if (delayprops != NULL && error == 0) { + (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED, + delayprops, errors); + } + } + + if (delayprops != NULL) { + /* + * 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. + */ + ASSERT(nvlist_merge(props, delayprops, 0) == 0); + nvlist_free(delayprops); + } + + /* + * Now that all props, initial and delayed, are set, report the prop + * errors to the caller. + */ + if (zc->zc_nvlist_dst_size != 0 && + (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 || + put_nvlist(zc, errors) != 0)) { + /* + * Caller made zc->zc_nvlist_dst less than the minimum expected + * size or supplied an invalid address. + */ + props_error = SET_ERROR(EINVAL); } zc->zc_cookie = off - fp->f_offset; @@ -4860,7 +4938,7 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) return (error); } -#ifdef sun +#ifdef illumos /* * We don't want to have a hard dependency * against some special symbols in sharefs @@ -4878,10 +4956,10 @@ int zfs_smbshare_inited; ddi_modhandle_t nfs_mod; ddi_modhandle_t sharefs_mod; ddi_modhandle_t smbsrv_mod; -#endif /* sun */ +#endif /* illumos */ kmutex_t zfs_share_lock; -#ifdef sun +#ifdef illumos static int zfs_init_sharefs() { @@ -4901,12 +4979,12 @@ zfs_init_sharefs() } return (0); } -#endif /* sun */ +#endif /* illumos */ static int zfs_ioc_share(zfs_cmd_t *zc) { -#ifdef sun +#ifdef illumos int error; int opcode; @@ -4997,9 +5075,9 @@ zfs_ioc_share(zfs_cmd_t *zc) return (error); -#else /* !sun */ +#else /* !illumos */ return (ENOSYS); -#endif /* !sun */ +#endif /* illumos */ } ace_t full_access[] = { @@ -5107,7 +5185,7 @@ zfs_ioc_diff(zfs_cmd_t *zc) return (error); } -#ifdef sun +#ifdef illumos /* * Remove all ACL files in shares dir */ @@ -5129,12 +5207,12 @@ zfs_smb_acl_purge(znode_t *dzp) zap_cursor_fini(&zc); return (error); } -#endif /* sun */ +#endif /* illumos */ static int zfs_ioc_smb_acl(zfs_cmd_t *zc) { -#ifdef sun +#ifdef illumos vnode_t *vp; znode_t *dzp; vnode_t *resourcevp = NULL; @@ -5258,9 +5336,9 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc) ZFS_EXIT(zfsvfs); return (error); -#else /* !sun */ +#else /* !illumos */ return (EOPNOTSUPP); -#endif /* !sun */ +#endif /* illumos */ } /* @@ -6013,7 +6091,7 @@ zfsdev_open(struct cdev *devp, int flag, int mode, struct thread *td) { int error = 0; -#ifdef sun +#ifdef illumos if (getminor(*devp) != 0) return (zvol_open(devp, flag, otyp, cr)); #endif @@ -6142,6 +6220,14 @@ zfsdev_ioctl(struct cdev *dev, u_long zcmd, caddr_t arg, int flag, goto out; } break; + case ZFS_IOCVER_RESUME: + if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_resume_t)) { + error = SET_ERROR(EFAULT); + goto out; + } + compat = B_TRUE; + cflag = ZFS_CMD_COMPAT_RESUME; + break; case ZFS_IOCVER_EDBP: if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_edbp_t)) { error = SET_ERROR(EFAULT); @@ -6358,7 +6444,7 @@ out: return (error); } -#ifdef sun +#ifdef illumos static int zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { @@ -6409,7 +6495,7 @@ zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) return (DDI_FAILURE); } -#endif /* sun */ +#endif /* illumos */ /* * OK, so this is a little weird. @@ -6420,7 +6506,7 @@ zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) * /dev/zfs has basically nothing to do except serve up ioctls, * so most of the standard driver entry points are in zvol.c. */ -#ifdef sun +#ifdef illumos static struct cb_ops zfs_cb_ops = { zfsdev_open, /* open */ zfsdev_close, /* close */ @@ -6469,7 +6555,7 @@ static struct modlinkage modlinkage = { (void *)&zfs_modldrv, NULL }; -#endif /* sun */ +#endif /* illumos */ static struct cdevsw zfs_cdevsw = { .d_version = D_VERSION, @@ -6502,7 +6588,7 @@ zfsdev_fini(void) static struct root_hold_token *zfs_root_token; struct proc *zfsproc; -#ifdef sun +#ifdef illumos int _init(void) { @@ -6565,7 +6651,7 @@ _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } -#endif /* sun */ +#endif /* illumos */ static int zfs__init(void); static int zfs__fini(void); @@ -6573,18 +6659,22 @@ static void zfs_shutdown(void *, int); static eventhandler_tag zfs_shutdown_event_tag; +#ifdef __FreeBSD__ #define ZFS_MIN_KSTACK_PAGES 4 +#endif int zfs__init(void) { +#ifdef __FreeBSD__ #if KSTACK_PAGES < ZFS_MIN_KSTACK_PAGES printf("ZFS NOTICE: KSTACK_PAGES is %d which could result in stack " "overflow panic!\nPlease consider adding " "'options KSTACK_PAGES=%d' to your kernel config\n", KSTACK_PAGES, ZFS_MIN_KSTACK_PAGES); #endif +#endif zfs_root_token = root_mount_hold("ZFS"); mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c index 30b3b52..6933ccd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/types.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c index ae24ef0..6a76513 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c @@ -820,7 +820,7 @@ top: static int zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) { -#ifdef sun +#ifdef illumos znode_t *zp; flock64_t fl; int error; @@ -843,10 +843,10 @@ zfs_replay_truncate(zfsvfs_t *zfsvfs, lr_truncate_t *lr, boolean_t byteswap) VN_RELE(ZTOV(zp)); return (error); -#else /* !sun */ +#else ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); return (EOPNOTSUPP); -#endif /* !sun */ +#endif } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 8e66044..fa6eac7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -23,6 +23,7 @@ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ @@ -133,6 +134,13 @@ zfs_sync(vfs_t *vfsp, int waitfor) if (panicstr) return (0); + /* + * Ignore the system syncher. ZFS already commits async data + * at zfs_txg_timeout intervals. + */ + if (waitfor == MNT_LAZY) + return (0); + if (vfsp != NULL) { /* * Sync a specific filesystem. @@ -848,6 +856,17 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) int i, error; uint64_t sa_obj; + /* + * XXX: Fix struct statfs so this isn't necessary! + * + * The 'osname' is used as the filesystem's special node, which means + * it must fit in statfs.f_mntfromname, or else it can't be + * enumerated, so libzfs_mnttab_find() returns NULL, which causes + * 'zfs unmount' to think it's not mounted when it is. + */ + if (strlen(osname) >= MNAMELEN) + return (SET_ERROR(ENAMETOOLONG)); + zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); /* @@ -1566,13 +1585,13 @@ zfs_mount(vfs_t *vfsp) * can be interrogated. */ if ((uap->flags & MS_DATA) && uap->datalen > 0) -#else +#else /* !illumos */ if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_ZFS)) return (SET_ERROR(EPERM)); if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL)) return (SET_ERROR(EINVAL)); -#endif /* ! illumos */ +#endif /* illumos */ /* * If full-owner-access is enabled and delegated administration is @@ -1675,14 +1694,14 @@ zfs_mount(vfs_t *vfsp) error = zfs_domount(vfsp, osname); PICKUP_GIANT(); -#ifdef sun +#ifdef illumos /* * Add an extra VFS_HOLD on our parent vfs so that it can't * disappear due to a forced unmount. */ if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap) VFS_HOLD(mvp->v_vfsp); -#endif /* sun */ +#endif out: return (error); @@ -1937,7 +1956,7 @@ zfs_umount(vfs_t *vfsp, int fflag) return (ret); } -#ifdef sun +#ifdef illumos if (!(fflag & MS_FORCE)) { /* * Check the number of active vnodes in the file system. @@ -2264,7 +2283,7 @@ zfs_freevfs(vfs_t *vfsp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; -#ifdef sun +#ifdef illumos /* * If this is a snapshot, we have an extra VFS_HOLD on our parent * from zfs_mount(). Release it here. If we came through @@ -2273,7 +2292,7 @@ zfs_freevfs(vfs_t *vfsp) */ if (zfsvfs->z_issnap && (vfsp != rootvfs)) VFS_RELE(zfsvfs->z_parent->z_vfs); -#endif /* sun */ +#endif zfsvfs_free(zfsvfs); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 5c26efe..04e1342 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -21,7 +21,8 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2007 Jeremy Teo */ @@ -334,7 +335,7 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred, ZFS_EXIT(zfsvfs); if (error) return (error); -#ifdef sun +#ifdef illumos if (ddi_copyout(&off, (void *)data, sizeof (off), flag)) return (SET_ERROR(EFAULT)); #else @@ -763,7 +764,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) ASSERT(uio->uio_loffset < zp->z_size); n = MIN(uio->uio_resid, zp->z_size - uio->uio_loffset); -#ifdef sun +#ifdef illumos if ((uio->uio_extflg == UIO_XUIO) && (((xuio_t *)uio)->xu_type == UIOTYPE_ZEROCOPY)) { int nblk; @@ -792,7 +793,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) } } } -#endif /* sun */ +#endif /* illumos */ while (n > 0) { nbytes = MIN(n, zfs_read_chunk_size - @@ -894,6 +895,16 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) &zp->z_pflags, 8); /* + * In a case vp->v_vfsp != zp->z_zfsvfs->z_vfs (e.g. snapshots) our + * callers might not be able to detect properly that we are read-only, + * so check it explicitly here. + */ + if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EROFS)); + } + + /* * If immutable or not appending then return EPERM */ if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || @@ -924,7 +935,7 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) return (error); } -#ifdef sun +#ifdef illumos /* * Pre-fault the pages to ensure slow (eg NFS) pages * don't hold up txg. @@ -935,7 +946,7 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) xuio = (xuio_t *)uio; else uio_prefaultpages(MIN(n, max_blksz), uio); -#endif /* sun */ +#endif /* * If in append mode, set the io offset pointer to eof. @@ -1187,10 +1198,10 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) ASSERT(tx_bytes == nbytes); n -= nbytes; -#ifdef sun +#ifdef illumos if (!xuio && n > 0) uio_prefaultpages(MIN(n, max_blksz), uio); -#endif /* sun */ +#endif } zfs_range_unlock(rl); @@ -1999,12 +2010,9 @@ top: dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); /* - * Mark this transaction as typically resulting in a net free of - * space, unless object removal will be delayed indefinitely - * (due to active holds on the vnode due to the file being open). + * Mark this transaction as typically resulting in a net free of space */ - if (may_delete_now) - dmu_tx_mark_netfree(tx); + dmu_tx_mark_netfree(tx); error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT); if (error) { @@ -2863,7 +2871,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, mutex_enter(&zp->z_lock); vap->va_type = IFTOVT(zp->z_mode); vap->va_mode = zp->z_mode & ~S_IFMT; -#ifdef sun +#ifdef illumos vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev; #else vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; @@ -2875,7 +2883,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, links = zp->z_links; vap->va_nlink = MIN(links, LINK_MAX); /* nlink_t limit! */ vap->va_size = zp->z_size; -#ifdef sun +#ifdef illumos vap->va_rdev = vp->v_rdev; #else if (vp->v_type == VBLK || vp->v_type == VCHR) @@ -4392,6 +4400,11 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, szp = VTOZ(svp); ZFS_VERIFY_ZP(szp); + if (szp->z_pflags & (ZFS_APPENDONLY | ZFS_IMMUTABLE | ZFS_READONLY)) { + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EPERM)); + } + /* * We check z_zfsvfs rather than v_vfsp here, because snapshots and the * ctldir appear to have the same v_vfsp. @@ -4497,7 +4510,7 @@ top: return (error); } -#ifdef sun +#ifdef illumos /* * zfs_null_putapage() is used when the file system has been force * unmounted. It just drops the pages. @@ -4725,7 +4738,7 @@ out: ZFS_EXIT(zfsvfs); return (error); } -#endif /* sun */ +#endif /* illumos */ /*ARGSUSED*/ void @@ -4778,7 +4791,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) rw_exit(&zfsvfs->z_teardown_inactive_lock); } -#ifdef sun +#ifdef illumos /* * Bounds-check the seek operation. * @@ -5176,6 +5189,16 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, return (SET_ERROR(EINVAL)); } + /* + * In a case vp->v_vfsp != zp->z_zfsvfs->z_vfs (e.g. snapshots) our + * callers might not be able to detect properly that we are read-only, + * so check it explicitly here. + */ + if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { + ZFS_EXIT(zfsvfs); + return (SET_ERROR(EROFS)); + } + if (error = convoff(vp, bfp, 0, offset)) { ZFS_EXIT(zfsvfs); return (error); @@ -5194,7 +5217,7 @@ zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, ZFS_EXIT(zfsvfs); return (error); } -#endif /* sun */ +#endif /* illumos */ CTASSERT(sizeof(struct zfid_short) <= sizeof(struct fid)); CTASSERT(sizeof(struct zfid_long) <= sizeof(struct fid)); @@ -5282,7 +5305,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, case _PC_FILESIZEBITS: *valp = 64; return (0); -#ifdef sun +#ifdef illumos case _PC_XATTR_EXISTS: zp = VTOZ(vp); zfsvfs = zp->z_zfsvfs; @@ -5320,16 +5343,16 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, case _PC_ACL_ENABLED: *valp = _ACL_ACE_ENABLED; return (0); -#endif /* sun */ +#endif /* illumos */ case _PC_MIN_HOLE_SIZE: *valp = (int)SPA_MINBLOCKSIZE; return (0); -#ifdef sun +#ifdef illumos case _PC_TIMESTAMP_RESOLUTION: /* nanosecond timestamp resolution */ *valp = 1L; return (0); -#endif /* sun */ +#endif case _PC_ACL_EXTENDED: *valp = 0; return (0); @@ -5388,7 +5411,7 @@ zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, return (error); } -#ifdef sun +#ifdef illumos /* * The smallest read we may consider to loan out an arcbuf. * This must be a power of 2. @@ -5719,7 +5742,7 @@ const fs_operation_def_t zfs_evnodeops_template[] = { VOPNAME_PATHCONF, { .vop_pathconf = zfs_pathconf }, NULL, NULL }; -#endif /* sun */ +#endif /* illumos */ static int ioflags(int ioflags) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c index 749ad53..04f0b6c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2007 Jeremy Teo */ @@ -172,7 +173,7 @@ static struct { } znode_move_stats; #endif /* ZNODE_STATS */ -#ifdef sun +#ifdef illumos static void zfs_znode_move_impl(znode_t *ozp, znode_t *nzp) { @@ -343,7 +344,7 @@ zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg) return (KMEM_CBRC_YES); } -#endif /* sun */ +#endif /* illumos */ void zfs_znode_init(void) @@ -362,12 +363,12 @@ zfs_znode_init(void) void zfs_znode_fini(void) { -#ifdef sun +#ifdef illumos /* * Cleanup vfs & vnode ops */ zfs_remove_op_tables(); -#endif /* sun */ +#endif /* * Cleanup zcache @@ -378,7 +379,7 @@ zfs_znode_fini(void) rw_destroy(&zfsvfs_lock); } -#ifdef sun +#ifdef illumos struct vnodeops *zfs_dvnodeops; struct vnodeops *zfs_fvnodeops; struct vnodeops *zfs_symvnodeops; @@ -470,7 +471,7 @@ zfs_create_op_tables() return (error); } -#endif /* sun */ +#endif /* illumos */ int zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) @@ -689,7 +690,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, case VDIR: zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ break; -#ifdef sun +#ifdef illumos case VBLK: case VCHR: { @@ -700,12 +701,12 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, vp->v_rdev = zfs_cmpldev(rdev); } break; -#endif /* sun */ +#endif case VFIFO: -#ifdef sun +#ifdef illumos case VSOCK: case VDOOR: -#endif /* sun */ +#endif vp->v_op = &zfs_fifoops; break; case VREG: @@ -714,14 +715,14 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, vp->v_op = &zfs_shareops; } break; -#ifdef sun +#ifdef illumos case VLNK: vn_setops(vp, zfs_symvnodeops); break; default: vn_setops(vp, zfs_evnodeops); break; -#endif /* sun */ +#endif } mutex_enter(&zfsvfs->z_znodes_lock); @@ -794,7 +795,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, gen = vap->va_nblocks; /* ditto */ } else { obj = 0; - gethrestime(&now); + vfs_timestamp(&now); gen = dmu_tx_get_txg(tx); } @@ -1175,13 +1176,13 @@ again: *zpp = zp; err = 0; } - sa_buf_rele(db, NULL); /* Don't let the vnode disappear after ZFS_OBJ_HOLD_EXIT. */ if (err == 0) VN_HOLD(vp); mutex_exit(&zp->z_lock); + sa_buf_rele(db, NULL); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); if (err == 0) { @@ -1436,7 +1437,7 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2], { timestruc_t now; - gethrestime(&now); + vfs_timestamp(&now); if (have_tx) { /* will sa_bulk_update happen really soon? */ zp->z_atime_dirty = 0; @@ -1500,7 +1501,7 @@ zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy); } -#ifdef sun +#ifdef illumos /* * This is a dummy interface used when pvn_vplist_dirty() should *not* * be calling back into the fs for a putpage(). E.g.: when truncating @@ -1514,7 +1515,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, ASSERT(0); return (0); } -#endif /* sun */ +#endif /* * Increase the file length diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c index 32a9ee7..0c407d7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index cce7fd1..f135af70 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ #include <sys/sysmacros.h> @@ -93,6 +94,9 @@ kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; extern vmem_t *zio_alloc_arena; #endif +#define ZIO_PIPELINE_CONTINUE 0x100 +#define ZIO_PIPELINE_STOP 0x101 + #define BP_SPANB(indblkshift, level) \ (((uint64_t)1) << ((level) * ((indblkshift) - SPA_BLKPTRSHIFT))) #define COMPARE_META_LEVEL 0x80000000ul @@ -1219,6 +1223,8 @@ zio_write_bp_init(zio_t *zio) zio->io_pipeline |= ZIO_STAGE_DDT_WRITE; return (ZIO_PIPELINE_CONTINUE); } + zio->io_bp_override = NULL; + BP_ZERO(bp); } if (!BP_IS_HOLE(bp) && bp->blk_birth == zio->io_txg) { @@ -1442,6 +1448,58 @@ zio_interrupt(zio_t *zio) zio_taskq_dispatch(zio, ZIO_TASKQ_INTERRUPT, B_FALSE); } +void +zio_delay_interrupt(zio_t *zio) +{ + /* + * The timeout_generic() function isn't defined in userspace, so + * rather than trying to implement the function, the zio delay + * functionality has been disabled for userspace builds. + */ + +#ifdef _KERNEL + /* + * If io_target_timestamp is zero, then no delay has been registered + * for this IO, thus jump to the end of this function and "skip" the + * delay; issuing it directly to the zio layer. + */ + if (zio->io_target_timestamp != 0) { + hrtime_t now = gethrtime(); + + if (now >= zio->io_target_timestamp) { + /* + * This IO has already taken longer than the target + * delay to complete, so we don't want to delay it + * any longer; we "miss" the delay and issue it + * directly to the zio layer. This is likely due to + * the target latency being set to a value less than + * the underlying hardware can satisfy (e.g. delay + * set to 1ms, but the disks take 10ms to complete an + * IO request). + */ + + DTRACE_PROBE2(zio__delay__miss, zio_t *, zio, + hrtime_t, now); + + zio_interrupt(zio); + } else { + hrtime_t diff = zio->io_target_timestamp - now; + + DTRACE_PROBE3(zio__delay__hit, zio_t *, zio, + hrtime_t, now, hrtime_t, diff); + + (void) timeout_generic(CALLOUT_NORMAL, + (void (*)(void *))zio_interrupt, zio, diff, 1, 0); + } + + return; + } +#endif + + DTRACE_PROBE1(zio__delay__skip, zio_t *, zio); + zio_interrupt(zio); +} + /* * Execute the I/O pipeline until one of the following occurs: * @@ -2662,6 +2720,18 @@ zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp) * Read, write and delete to physical devices * ========================================================================== */ + + +/* + * Issue an I/O to the underlying vdev. Typically the issue pipeline + * stops after this stage and will resume upon I/O completion. + * However, there are instances where the vdev layer may need to + * continue the pipeline when an I/O was not issued. Since the I/O + * that was sent to the vdev layer might be different than the one + * currently active in the pipeline (see vdev_queue_io()), we explicitly + * force the underlying vdev layers to call either zio_execute() or + * zio_interrupt() to ensure that the pipeline continues with the correct I/O. + */ static int zio_vdev_io_start(zio_t *zio) { @@ -2680,7 +2750,8 @@ zio_vdev_io_start(zio_t *zio) /* * The mirror_ops handle multiple DVAs in a single BP. */ - return (vdev_mirror_ops.vdev_op_io_start(zio)); + vdev_mirror_ops.vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE && @@ -2694,7 +2765,7 @@ zio_vdev_io_start(zio_t *zio) * can quickly react to certain workloads. In particular, we care * about non-scrubbing, top-level reads and writes with the following * characteristics: - * - synchronous writes of user data to non-slog devices + * - synchronous writes of user data to non-slog devices * - any reads of user data * When these conditions are met, adjust the timestamp of spa_last_io * which allows the scan thread to adjust its workload accordingly. @@ -2711,8 +2782,7 @@ zio_vdev_io_start(zio_t *zio) align = 1ULL << vd->vdev_top->vdev_ashift; - if ((!(zio->io_flags & ZIO_FLAG_PHYSICAL) || - (vd->vdev_top->vdev_physical_ashift > SPA_MINBLOCKSHIFT)) && + if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) && P2PHASE(zio->io_size, align) != 0) { /* Transform logical writes to be a full physical block size. */ uint64_t asize = P2ROUNDUP(zio->io_size, align); @@ -2798,10 +2868,8 @@ zio_vdev_io_start(zio_t *zio) return (ZIO_PIPELINE_STOP); } - ret = vd->vdev_ops->vdev_op_io_start(zio); - ASSERT(ret == ZIO_PIPELINE_STOP); - - return (ret); + vd->vdev_ops->vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c index 6ba64e0..dac118a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c @@ -138,10 +138,16 @@ zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { #endif }; +/* + * The flag corresponding to the "verify" in dedup=[checksum,]verify + * must be cleared first, so callers should use ZIO_CHECKSUM_MASK. + */ spa_feature_t zio_checksum_to_feature(enum zio_checksum cksum) { #ifdef illumos + VERIFY((cksum & ~ZIO_CHECKSUM_MASK) == 0); + switch (cksum) { case ZIO_CHECKSUM_SHA512: return (SPA_FEATURE_SHA512); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c index 0a7f4e4..26f59af 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. */ /* @@ -49,15 +49,53 @@ uint32_t zio_injection_enabled; +/* + * Data describing each zinject handler registered on the system, and + * contains the list node linking the handler in the global zinject + * handler list. + */ typedef struct inject_handler { int zi_id; spa_t *zi_spa; zinject_record_t zi_record; + uint64_t *zi_lanes; + int zi_next_lane; list_node_t zi_link; } inject_handler_t; +/* + * List of all zinject handlers registered on the system, protected by + * the inject_lock defined below. + */ static list_t inject_handlers; + +/* + * This protects insertion into, and traversal of, the inject handler + * list defined above; as well as the inject_delay_count. Any time a + * handler is inserted or removed from the list, this lock should be + * taken as a RW_WRITER; and any time traversal is done over the list + * (without modification to it) this lock should be taken as a RW_READER. + */ static krwlock_t inject_lock; + +/* + * This holds the number of zinject delay handlers that have been + * registered on the system. It is protected by the inject_lock defined + * above. Thus modifications to this count must be a RW_WRITER of the + * inject_lock, and reads of this count must be (at least) a RW_READER + * of the lock. + */ +static int inject_delay_count = 0; + +/* + * This lock is used only in zio_handle_io_delay(), refer to the comment + * in that function for more details. + */ +static kmutex_t inject_delay_mtx; + +/* + * Used to assign unique identifying numbers to each new zinject handler. + */ static int inject_next_id = 1; /* @@ -360,32 +398,164 @@ spa_handle_ignored_writes(spa_t *spa) rw_exit(&inject_lock); } -uint64_t +hrtime_t zio_handle_io_delay(zio_t *zio) { vdev_t *vd = zio->io_vd; - inject_handler_t *handler; - uint64_t seconds = 0; - - if (zio_injection_enabled == 0) - return (0); + inject_handler_t *min_handler = NULL; + hrtime_t min_target = 0; rw_enter(&inject_lock, RW_READER); - for (handler = list_head(&inject_handlers); handler != NULL; - handler = list_next(&inject_handlers, handler)) { + /* + * inject_delay_count is a subset of zio_injection_enabled that + * is only incremented for delay handlers. These checks are + * mainly added to remind the reader why we're not explicitly + * checking zio_injection_enabled like the other functions. + */ + IMPLY(inject_delay_count > 0, zio_injection_enabled > 0); + IMPLY(zio_injection_enabled == 0, inject_delay_count == 0); + + /* + * If there aren't any inject delay handlers registered, then we + * can short circuit and simply return 0 here. A value of zero + * informs zio_delay_interrupt() that this request should not be + * delayed. This short circuit keeps us from acquiring the + * inject_delay_mutex unnecessarily. + */ + if (inject_delay_count == 0) { + rw_exit(&inject_lock); + return (0); + } + + /* + * Each inject handler has a number of "lanes" associated with + * it. Each lane is able to handle requests independently of one + * another, and at a latency defined by the inject handler + * record's zi_timer field. Thus if a handler in configured with + * a single lane with a 10ms latency, it will delay requests + * such that only a single request is completed every 10ms. So, + * if more than one request is attempted per each 10ms interval, + * the average latency of the requests will be greater than + * 10ms; but if only a single request is submitted each 10ms + * interval the average latency will be 10ms. + * + * We need to acquire this mutex to prevent multiple concurrent + * threads being assigned to the same lane of a given inject + * handler. The mutex allows us to perform the following two + * operations atomically: + * + * 1. determine the minimum handler and minimum target + * value of all the possible handlers + * 2. update that minimum handler's lane array + * + * Without atomicity, two (or more) threads could pick the same + * lane in step (1), and then conflict with each other in step + * (2). This could allow a single lane handler to process + * multiple requests simultaneously, which shouldn't be possible. + */ + mutex_enter(&inject_delay_mtx); + for (inject_handler_t *handler = list_head(&inject_handlers); + handler != NULL; handler = list_next(&inject_handlers, handler)) { if (handler->zi_record.zi_cmd != ZINJECT_DELAY_IO) continue; - if (vd->vdev_guid == handler->zi_record.zi_guid) { - seconds = handler->zi_record.zi_timer; - break; + if (vd->vdev_guid != handler->zi_record.zi_guid) + continue; + + /* + * Defensive; should never happen as the array allocation + * occurs prior to inserting this handler on the list. + */ + ASSERT3P(handler->zi_lanes, !=, NULL); + + /* + * This should never happen, the zinject command should + * prevent a user from setting an IO delay with zero lanes. + */ + ASSERT3U(handler->zi_record.zi_nlanes, !=, 0); + + ASSERT3U(handler->zi_record.zi_nlanes, >, + handler->zi_next_lane); + + /* + * We want to issue this IO to the lane that will become + * idle the soonest, so we compare the soonest this + * specific handler can complete the IO with all other + * handlers, to find the lowest value of all possible + * lanes. We then use this lane to submit the request. + * + * Since each handler has a constant value for its + * delay, we can just use the "next" lane for that + * handler; as it will always be the lane with the + * lowest value for that particular handler (i.e. the + * lane that will become idle the soonest). This saves a + * scan of each handler's lanes array. + * + * There's two cases to consider when determining when + * this specific IO request should complete. If this + * lane is idle, we want to "submit" the request now so + * it will complete after zi_timer milliseconds. Thus, + * we set the target to now + zi_timer. + * + * If the lane is busy, we want this request to complete + * zi_timer milliseconds after the lane becomes idle. + * Since the 'zi_lanes' array holds the time at which + * each lane will become idle, we use that value to + * determine when this request should complete. + */ + hrtime_t idle = handler->zi_record.zi_timer + gethrtime(); + hrtime_t busy = handler->zi_record.zi_timer + + handler->zi_lanes[handler->zi_next_lane]; + hrtime_t target = MAX(idle, busy); + + if (min_handler == NULL) { + min_handler = handler; + min_target = target; + continue; } + ASSERT3P(min_handler, !=, NULL); + ASSERT3U(min_target, !=, 0); + + /* + * We don't yet increment the "next lane" variable since + * we still might find a lower value lane in another + * handler during any remaining iterations. Once we're + * sure we've selected the absolute minimum, we'll claim + * the lane and increment the handler's "next lane" + * field below. + */ + + if (target < min_target) { + min_handler = handler; + min_target = target; + } } + + /* + * 'min_handler' will be NULL if no IO delays are registered for + * this vdev, otherwise it will point to the handler containing + * the lane that will become idle the soonest. + */ + if (min_handler != NULL) { + ASSERT3U(min_target, !=, 0); + min_handler->zi_lanes[min_handler->zi_next_lane] = min_target; + + /* + * If we've used all possible lanes for this handler, + * loop back and start using the first lane again; + * otherwise, just increment the lane index. + */ + min_handler->zi_next_lane = (min_handler->zi_next_lane + 1) % + min_handler->zi_record.zi_nlanes; + } + + mutex_exit(&inject_delay_mtx); rw_exit(&inject_lock); - return (seconds); + + return (min_target); } /* @@ -409,6 +579,24 @@ zio_inject_fault(char *name, int flags, int *id, zinject_record_t *record) if ((error = spa_reset(name)) != 0) return (error); + if (record->zi_cmd == ZINJECT_DELAY_IO) { + /* + * A value of zero for the number of lanes or for the + * delay time doesn't make sense. + */ + if (record->zi_timer == 0 || record->zi_nlanes == 0) + return (SET_ERROR(EINVAL)); + + /* + * The number of lanes is directly mapped to the size of + * an array used by the handler. Thus, to ensure the + * user doesn't trigger an allocation that's "too large" + * we cap the number of lanes here. + */ + if (record->zi_nlanes >= UINT16_MAX) + return (SET_ERROR(EINVAL)); + } + if (!(flags & ZINJECT_NULL)) { /* * spa_inject_ref() will add an injection reference, which will @@ -420,11 +608,34 @@ zio_inject_fault(char *name, int flags, int *id, zinject_record_t *record) handler = kmem_alloc(sizeof (inject_handler_t), KM_SLEEP); + handler->zi_spa = spa; + handler->zi_record = *record; + + if (handler->zi_record.zi_cmd == ZINJECT_DELAY_IO) { + handler->zi_lanes = kmem_zalloc( + sizeof (*handler->zi_lanes) * + handler->zi_record.zi_nlanes, KM_SLEEP); + handler->zi_next_lane = 0; + } else { + handler->zi_lanes = NULL; + handler->zi_next_lane = 0; + } + rw_enter(&inject_lock, RW_WRITER); + /* + * We can't move this increment into the conditional + * above because we need to hold the RW_WRITER lock of + * inject_lock, and we don't want to hold that while + * allocating the handler's zi_lanes array. + */ + if (handler->zi_record.zi_cmd == ZINJECT_DELAY_IO) { + ASSERT3S(inject_delay_count, >=, 0); + inject_delay_count++; + ASSERT3S(inject_delay_count, >, 0); + } + *id = handler->zi_id = inject_next_id++; - handler->zi_spa = spa; - handler->zi_record = *record; list_insert_tail(&inject_handlers, handler); atomic_inc_32(&zio_injection_enabled); @@ -502,9 +713,23 @@ zio_clear_fault(int id) return (SET_ERROR(ENOENT)); } + if (handler->zi_record.zi_cmd == ZINJECT_DELAY_IO) { + ASSERT3S(inject_delay_count, >, 0); + inject_delay_count--; + ASSERT3S(inject_delay_count, >=, 0); + } + list_remove(&inject_handlers, handler); rw_exit(&inject_lock); + if (handler->zi_record.zi_cmd == ZINJECT_DELAY_IO) { + ASSERT3P(handler->zi_lanes, !=, NULL); + kmem_free(handler->zi_lanes, sizeof (*handler->zi_lanes) * + handler->zi_record.zi_nlanes); + } else { + ASSERT3P(handler->zi_lanes, ==, NULL); + } + spa_inject_delref(handler->zi_spa); kmem_free(handler, sizeof (inject_handler_t)); atomic_dec_32(&zio_injection_enabled); @@ -516,6 +741,7 @@ void zio_inject_init(void) { rw_init(&inject_lock, NULL, RW_DEFAULT, NULL); + mutex_init(&inject_delay_mtx, NULL, MUTEX_DEFAULT, NULL); list_create(&inject_handlers, sizeof (inject_handler_t), offsetof(inject_handler_t, zi_link)); } @@ -524,5 +750,6 @@ void zio_inject_fini(void) { list_destroy(&inject_handlers); + mutex_destroy(&inject_delay_mtx); rw_destroy(&inject_lock); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index ce8eed3..d4d10e3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -29,6 +29,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org> */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/os/callb.c b/sys/cddl/contrib/opensolaris/uts/common/os/callb.c index da397a5..da47908 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/os/callb.c +++ b/sys/cddl/contrib/opensolaris/uts/common/os/callb.c @@ -368,7 +368,7 @@ callb_unlock_table(void) mutex_exit(&ct->ct_lock); } -#ifdef sun +#ifdef illumos /* * Return a boolean value indicating whether a particular kernel thread is * stopped in accordance with the cpr callback protocol. If returning @@ -432,7 +432,7 @@ callb_is_stopped(kthread_id_t tp, caddr_t *thread_name) mutex_exit(&ct->ct_lock); return (ret_val); } -#endif /* sun */ +#endif /* illumos */ SYSINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_init, NULL); SYSUNINIT(sol_callb, SI_SUB_DRIVERS, SI_ORDER_FIRST, callb_fini, NULL); diff --git a/sys/cddl/contrib/opensolaris/uts/common/os/fm.c b/sys/cddl/contrib/opensolaris/uts/common/os/fm.c index 66a860d..57b2335 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/os/fm.c +++ b/sys/cddl/contrib/opensolaris/uts/common/os/fm.c @@ -79,7 +79,7 @@ static const char *fm_url = "http://www.sun.com/msg"; static const char *fm_msgid = "SUNOS-8000-0G"; static char *volatile fm_panicstr = NULL; -#ifdef sun +#ifdef illumos errorq_t *ereport_errorq; #endif void *ereport_dumpbuf; @@ -112,7 +112,7 @@ static struct erpt_kstat erpt_kstat_data = { { "payload-set-failed", KSTAT_DATA_UINT64 } }; -#ifdef sun +#ifdef illumos /*ARGSUSED*/ static void fm_drain(void *private, void *data, errorq_elem_t *eep) @@ -131,7 +131,7 @@ fm_init(void) { kstat_t *ksp; -#ifdef sun +#ifdef illumos (void) sysevent_evc_bind(FM_ERROR_CHAN, &ereport_chan, EVCH_CREAT | EVCH_HOLD_PEND); @@ -145,7 +145,7 @@ fm_init(void) if (ereport_size == 0) ereport_size = ERPT_DATA_SZ; -#ifdef sun +#ifdef illumos ereport_errorq = errorq_nvcreate("fm_ereport_queue", (errorq_func_t)fm_drain, NULL, ereport_qlen, ereport_size, FM_ERR_PIL, ERRORQ_VITAL); @@ -170,7 +170,7 @@ fm_init(void) } } -#ifdef sun +#ifdef illumos /* * Formatting utility function for fm_nvprintr. We attempt to wrap chunks of * output so they aren't split across console lines, and return the end column. @@ -528,7 +528,7 @@ fm_ereport_post(nvlist_t *ereport, int evc_flag) return; } -#ifdef sun +#ifdef illumos if (sysevent_evc_bind(FM_ERROR_CHAN, &error_chan, EVCH_CREAT|EVCH_HOLD_PEND) != 0) { atomic_inc_64(&erpt_kstat_data.erpt_dropped.value.ui64); @@ -1262,7 +1262,7 @@ fm_ena_time_get(uint64_t ena) return (time); } -#ifdef sun +#ifdef illumos /* * Convert a getpcstack() trace to symbolic name+offset, and add the resulting * string array to a Fault Management ereport as FM_EREPORT_PAYLOAD_NAME_STACK. @@ -1290,7 +1290,7 @@ fm_payload_stack_add(nvlist_t *payload, const pc_t *stack, int depth) } #endif -#ifdef sun +#ifdef illumos void print_msg_hwerr(ctid_t ct_id, proc_t *p) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h index 2d1987b..5288141 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h @@ -27,7 +27,7 @@ #ifndef _CTF_H #define _CTF_H -#if defined(sun) +#ifdef illumos #pragma ident "%Z%%M% %I% %E% SMI" #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h index 8e3f4ca..6b7ab01 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h @@ -69,7 +69,7 @@ typedef struct ctf_sect { const char *cts_name; /* section name (if any) */ ulong_t cts_type; /* section type (ELF SHT_... value) */ ulong_t cts_flags; /* section flags (ELF SHF_... value) */ -#if defined(sun) +#ifdef illumos const void *cts_data; /* pointer to section data */ #else void *cts_data; /* pointer to section data */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index ca73689..d449294 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -54,7 +54,7 @@ extern "C" { #include <sys/types.h> #include <sys/modctl.h> #include <sys/processor.h> -#if defined(sun) +#ifdef illumos #include <sys/systm.h> #else #include <sys/cpuvar.h> @@ -65,7 +65,7 @@ extern "C" { typedef int model_t; #endif #include <sys/ctf_api.h> -#if defined(sun) +#ifdef illumos #include <sys/cyclic.h> #include <sys/int_limits.h> #else @@ -257,7 +257,7 @@ typedef enum dtrace_probespec { #define DIF_VAR_ERRNO 0x0120 /* thread errno */ #define DIF_VAR_EXECARGS 0x0121 /* process arguments */ -#if !defined(sun) +#ifndef illumos #define DIF_VAR_CPU 0x0200 #endif @@ -1277,7 +1277,7 @@ typedef struct dtrace_providerdesc { * pseudodevice driver. These ioctls comprise the user-kernel interface to * DTrace. */ -#if defined(sun) +#ifdef illumos #define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) #define DTRACEIOC_PROVIDER (DTRACEIOC | 1) /* provider query */ #define DTRACEIOC_PROBES (DTRACEIOC | 2) /* probe query */ @@ -1408,7 +1408,7 @@ typedef struct { * helpers and should no longer be used. No other ioctls are valid on the * helper minor node. */ -#if defined(sun) +#ifdef illumos #define DTRACEHIOC (('d' << 24) | ('t' << 16) | ('h' << 8)) #define DTRACEHIOC_ADD (DTRACEHIOC | 1) /* add helper */ #define DTRACEHIOC_REMOVE (DTRACEHIOC | 2) /* remove helper */ @@ -1423,7 +1423,7 @@ typedef struct dof_helper { char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ uint64_t dofhp_addr; /* base address of object */ uint64_t dofhp_dof; /* address of helper DOF */ -#if !defined(sun) +#ifndef illumos int gen; #endif } dof_helper_t; @@ -2325,7 +2325,7 @@ typedef enum dtrace_vtime_state { DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ } dtrace_vtime_state_t; -#if defined(sun) +#ifdef illumos extern dtrace_vtime_state_t dtrace_vtime_active; #endif extern void dtrace_vtime_switch(kthread_t *next); @@ -2337,7 +2337,7 @@ extern void dtrace_vtime_disable(void); struct regs; struct reg; -#if defined(sun) +#ifdef illumos extern int (*dtrace_pid_probe_ptr)(struct reg *); extern int (*dtrace_return_probe_ptr)(struct reg *); extern void (*dtrace_fasttrap_fork_ptr)(proc_t *, proc_t *); @@ -2356,7 +2356,7 @@ extern void dtrace_membar_producer(void); extern void dtrace_membar_consumer(void); extern void (*dtrace_cpu_init)(processorid_t); -#if defined(sun) +#ifdef illumos extern void (*dtrace_modload)(modctl_t *); extern void (*dtrace_modunload)(modctl_t *); #endif @@ -2370,7 +2370,7 @@ extern void (*dtrace_debugger_init)(void); extern void (*dtrace_debugger_fini)(void); extern dtrace_cacheid_t dtrace_predcache_id; -#if defined(sun) +#ifdef illumos extern hrtime_t dtrace_gethrtime(void); #else void dtrace_debug_printf(const char *, ...) __printflike(1, 2); @@ -2399,7 +2399,7 @@ extern int dtrace_blksuword32(uintptr_t, uint32_t *, int); extern void dtrace_getfsr(uint64_t *); #endif -#if !defined(sun) +#ifndef illumos extern void dtrace_helpers_duplicate(proc_t *, proc_t *); extern void dtrace_helpers_destroy(proc_t *); #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h index f9e9689..a65d1ae 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h @@ -50,7 +50,7 @@ extern "C" { */ #include <sys/dtrace.h> -#if !defined(sun) +#ifndef illumos #ifdef __sparcv9 typedef uint32_t pc_t; #else @@ -1122,7 +1122,7 @@ typedef struct dtrace_cred { * dtrace_state structure. */ struct dtrace_state { -#if defined(sun) +#ifdef illumos dev_t dts_dev; /* device */ #else struct cdev *dts_dev; /* device */ @@ -1140,7 +1140,7 @@ struct dtrace_state { int dts_nspeculations; /* number of speculations */ int dts_naggregations; /* number of aggregations */ dtrace_aggregation_t **dts_aggregations; /* aggregation array */ -#if defined(sun) +#ifdef illumos vmem_t *dts_aggid_arena; /* arena for aggregation IDs */ #else struct unrhdr *dts_aggid_arena; /* arena for aggregation IDs */ @@ -1152,7 +1152,7 @@ struct dtrace_state { uint32_t dts_dblerrors; /* errors in ERROR probes */ uint32_t dts_reserve; /* space reserved for END */ hrtime_t dts_laststatus; /* time of last status */ -#if defined(sun) +#ifdef illumos cyclic_id_t dts_cleaner; /* cleaning cyclic */ cyclic_id_t dts_deadman; /* deadman cyclic */ #else @@ -1270,7 +1270,7 @@ typedef struct dtrace_toxrange { uintptr_t dtt_limit; /* limit of toxic range */ } dtrace_toxrange_t; -#if defined(sun) +#ifdef illumos extern uint64_t dtrace_getarg(int, int); #else extern uint64_t __noinline dtrace_getarg(int, int); @@ -1300,7 +1300,7 @@ extern void dtrace_probe_error(dtrace_state_t *, dtrace_epid_t, int, int, int, uintptr_t); extern int dtrace_assfail(const char *, const char *, int); extern int dtrace_attached(void); -#if defined(sun) +#ifdef illumos extern hrtime_t dtrace_gethrestime(void); #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap.h index 431307f..ec3582f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap.h @@ -37,7 +37,7 @@ extern "C" { #endif -#if defined(sun) +#ifdef illumos #define FASTTRAPIOC (('m' << 24) | ('r' << 16) | ('f' << 8)) #define FASTTRAPIOC_MAKEPROBE (FASTTRAPIOC | 1) #define FASTTRAPIOC_GETINSTR (FASTTRAPIOC | 2) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h index 6f591fa..cae9193 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h @@ -79,7 +79,7 @@ extern "C" { * until it exits. */ -#if !defined(sun) +#ifndef illumos typedef struct fasttrap_scrblock { vm_offset_t ftsb_addr; /* address of a scratch block */ LIST_ENTRY(fasttrap_scrblock) ftsb_next;/* next block in list */ @@ -99,7 +99,7 @@ typedef struct fasttrap_proc { uint64_t ftpc_rcount; /* count of extant providers */ kmutex_t ftpc_mtx; /* lock on all but acount */ struct fasttrap_proc *ftpc_next; /* next proc in hash chain */ -#if !defined(sun) +#ifndef illumos LIST_HEAD(, fasttrap_scrblock) ftpc_scrblks; /* mapped scratch blocks */ LIST_HEAD(, fasttrap_scrspace) ftpc_fscr; /* free scratch space */ LIST_HEAD(, fasttrap_scrspace) ftpc_ascr; /* used scratch space */ @@ -198,7 +198,7 @@ typedef struct fasttrap_hash { #endif extern void fasttrap_sigtrap(proc_t *, kthread_t *, uintptr_t); -#if !defined(sun) +#ifndef illumos extern fasttrap_scrspace_t *fasttrap_scraddr(struct thread *, fasttrap_proc_t *); #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h index 809ce9b..3818616 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -25,6 +25,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>. All rights reserved. + * Copyright (c) 2014 Integros [integros.com] */ /* Portions Copyright 2010 Robert Milkowski */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h index f515614..29d616b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h @@ -235,7 +235,7 @@ extern "C" { /* * Define the appropriate "processor characteristics" */ -#if defined(sun) +#ifdef illumos #define _LITTLE_ENDIAN #endif #define _STACK_GROWS_DOWNWARD @@ -302,7 +302,7 @@ extern "C" { /* * Define the appropriate "processor characteristics" */ -#if defined(sun) +#ifdef illumos #define _LITTLE_ENDIAN #endif #define _STACK_GROWS_DOWNWARD @@ -504,7 +504,7 @@ extern "C" { * Define the appropriate "processor characteristics" shared between * all Solaris on SPARC systems. */ -#if defined(sun) +#ifdef illumos #define _BIG_ENDIAN #endif #define _STACK_GROWS_DOWNWARD diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h b/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h index 8c5739b..a7d58e5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/procset.h @@ -143,7 +143,7 @@ typedef struct procset { #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ -#if defined(sun) +#ifdef illumos #ifdef _KERNEL struct proc; diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent.h b/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent.h index 3558c2a..777d748 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent.h @@ -214,7 +214,7 @@ typedef struct sysevent_value { #define EVCH_SET_CHAN_LEN 3 /* Set event queue length */ #define EVCH_CMD_LAST EVCH_SET_CHAN_LEN /* Last command */ -#ifdef sun +#ifdef illumos /* * Shared user/kernel event channel interface definitions */ @@ -228,11 +228,11 @@ extern int sysevent_evc_publish(evchan_t *, const char *, const char *, extern int sysevent_evc_control(evchan_t *, int, ...); extern int sysevent_evc_setpropnvl(evchan_t *, nvlist_t *); extern int sysevent_evc_getpropnvl(evchan_t *, nvlist_t **); -#endif /* sun */ +#endif /* illumos */ #ifndef _KERNEL -#ifdef sun +#ifdef illumos /* * Userland-only event channel interfaces */ @@ -254,7 +254,7 @@ extern void sysevent_subattr_thrsetup(sysevent_subattr_t *, extern int sysevent_evc_xsubscribe(evchan_t *, const char *, const char *, int (*)(sysevent_t *, void *), void *, uint32_t, sysevent_subattr_t *); -#endif /* sun */ +#endif /* illumos */ #else @@ -270,7 +270,7 @@ extern int sysevent_add_attr(sysevent_attr_list_t **, char *, extern void sysevent_free_attr(sysevent_attr_list_t *); extern int sysevent_attach_attributes(sysevent_t *, sysevent_attr_list_t *); extern void sysevent_detach_attributes(sysevent_t *); -#ifdef sun +#ifdef illumos extern char *sysevent_get_class_name(sysevent_t *); extern char *sysevent_get_subclass_name(sysevent_t *); extern uint64_t sysevent_get_seq(sysevent_t *); @@ -278,7 +278,7 @@ extern void sysevent_get_time(sysevent_t *, hrtime_t *); extern size_t sysevent_get_size(sysevent_t *); extern char *sysevent_get_pub(sysevent_t *); extern int sysevent_get_attr_list(sysevent_t *, nvlist_t **); -#endif /* sun */ +#endif /* illumos */ #endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h index 0d5a35a..aa84f36 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h @@ -115,7 +115,7 @@ extern unsigned char bcd_to_byte[256]; #define L_MAXMIN L_MAXMIN32 #endif -#ifdef sun +#ifdef illumos #ifdef _KERNEL /* major part of a device internal to the kernel */ @@ -175,7 +175,7 @@ extern unsigned char bcd_to_byte[256]; #define getemajor(x) (major_t)((((dev_t)(x) >> L_BITSMINOR) > L_MAXMAJ) ? \ NODEV : (((dev_t)(x) >> L_BITSMINOR) & L_MAXMAJ)) #define geteminor(x) (minor_t)((x) & L_MAXMIN) -#endif /* sun */ +#endif /* illumos */ /* * These are versions of the kernel routines for compressing and diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/u8_textprep.h b/sys/cddl/contrib/opensolaris/uts/common/sys/u8_textprep.h index 77c9c0b..1496fa3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/u8_textprep.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/u8_textprep.h @@ -36,7 +36,7 @@ extern "C" { #endif -#ifdef sun +#ifdef illumos /* * Unicode encoding conversion functions and their macros. */ @@ -58,7 +58,7 @@ extern int uconv_u32tou16(const uint32_t *, size_t *, uint16_t *, size_t *, extern int uconv_u32tou8(const uint32_t *, size_t *, uchar_t *, size_t *, int); extern int uconv_u8tou16(const uchar_t *, size_t *, uint16_t *, size_t *, int); extern int uconv_u8tou32(const uchar_t *, size_t *, uint32_t *, size_t *, int); -#endif /* sun */ +#endif /* illumos */ /* * UTF-8 text preparation functions and their macros. diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c index 8df1090..5d60a07 100644 --- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c +++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c @@ -28,7 +28,7 @@ * Use is subject to license terms. */ -#if defined(sun) +#ifdef illumos #pragma ident "%Z%%M% %I% %E% SMI" #endif @@ -37,7 +37,7 @@ #include <sys/dtrace.h> #include <sys/dtrace_impl.h> #include <sys/cmn_err.h> -#if defined(sun) +#ifdef illumos #include <sys/regset.h> #include <sys/privregs.h> #include <sys/segments.h> @@ -53,7 +53,7 @@ #include <machine/pcb.h> #endif #include <sys/sysmacros.h> -#if defined(sun) +#ifdef illumos #include <sys/trap.h> #include <sys/archsystm.h> #else @@ -97,7 +97,7 @@ uwrite(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr) return (proc_ops(UIO_WRITE, p, kaddr, uaddr, len)); } -#endif /* sun */ +#endif /* illumos */ #ifdef __i386__ #define r_rax r_eax #define r_rbx r_ebx @@ -747,11 +747,11 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, fasttrap_tracepoint_t *tp; fasttrap_bucket_t *bucket; fasttrap_id_t *id; -#if defined(sun) +#ifdef illumos kmutex_t *pid_mtx; #endif -#if defined(sun) +#ifdef illumos pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock; mutex_enter(pid_mtx); #endif @@ -769,7 +769,7 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, * is not essential to the correct execution of the process. */ if (tp == NULL) { -#if defined(sun) +#ifdef illumos mutex_exit(pid_mtx); #endif return; @@ -792,7 +792,7 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, rp->r_rax, rp->r_rbx, 0, 0); } -#if defined(sun) +#ifdef illumos mutex_exit(pid_mtx); #endif } @@ -800,7 +800,7 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, static void fasttrap_sigsegv(proc_t *p, kthread_t *t, uintptr_t addr) { -#if defined(sun) +#ifdef illumos sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); sqp->sq_info.si_signo = SIGSEGV; @@ -1001,13 +1001,13 @@ int fasttrap_pid_probe(struct reg *rp) { proc_t *p = curproc; -#if !defined(sun) +#ifndef illumos proc_t *pp; #endif uintptr_t pc = rp->r_rip - 1; uintptr_t new_pc = 0; fasttrap_bucket_t *bucket; -#if defined(sun) +#ifdef illumos kmutex_t *pid_mtx; #endif fasttrap_tracepoint_t *tp, tp_local; @@ -1044,7 +1044,7 @@ fasttrap_pid_probe(struct reg *rp) * parent. We know that there's only one thread of control in such a * process: this one. */ -#if defined(sun) +#ifdef illumos while (p->p_flag & SVFORK) { p = p->p_parent; } @@ -1082,7 +1082,7 @@ fasttrap_pid_probe(struct reg *rp) * fasttrap_ioctl), or somehow we have mislaid this tracepoint. */ if (tp == NULL) { -#if defined(sun) +#ifdef illumos mutex_exit(pid_mtx); #else _PRELE(p); @@ -1209,7 +1209,7 @@ fasttrap_pid_probe(struct reg *rp) * tracepoint again later if we need to light up any return probes. */ tp_local = *tp; -#if defined(sun) +#ifdef illumos mutex_exit(pid_mtx); #else PROC_UNLOCK(p); @@ -1537,7 +1537,7 @@ fasttrap_pid_probe(struct reg *rp) uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 7]; #endif uint_t i = 0; -#if defined(sun) +#ifdef illumos klwp_t *lwp = ttolwp(curthread); /* @@ -1558,7 +1558,7 @@ fasttrap_pid_probe(struct reg *rp) addr = USD_GETBASE(&lwp->lwp_pcb.pcb_gsdesc); addr += sizeof (void *); #endif -#else +#else /* !illumos */ fasttrap_scrspace_t *scrspace; scrspace = fasttrap_scraddr(curthread, tp->ftt_proc); if (scrspace == NULL) { @@ -1574,7 +1574,7 @@ fasttrap_pid_probe(struct reg *rp) break; } addr = scrspace->ftss_addr; -#endif /* sun */ +#endif /* illumos */ /* * Generic Instruction Tracing @@ -1760,7 +1760,7 @@ fasttrap_pid_probe(struct reg *rp) ASSERT(i <= sizeof (scratch)); -#if defined(sun) +#ifdef illumos if (fasttrap_copyout(scratch, (char *)addr, i)) { #else if (uwrite(p, scratch, i, addr)) { @@ -1822,7 +1822,7 @@ done: rp->r_rip = new_pc; -#if !defined(sun) +#ifndef illumos PROC_LOCK(p); proc_write_regs(curthread, rp); _PRELE(p); @@ -1844,7 +1844,7 @@ fasttrap_return_probe(struct reg *rp) curthread->t_dtrace_scrpc = 0; curthread->t_dtrace_astpc = 0; -#if defined(sun) +#ifdef illumos /* * Treat a child created by a call to vfork(2) as if it were its * parent. We know that there's only one thread of control in such a @@ -1917,7 +1917,7 @@ fasttrap_getreg(struct reg *rp, uint_t reg) case REG_ERR: return (rp->r_err); case REG_RIP: return (rp->r_rip); case REG_CS: return (rp->r_cs); -#if defined(sun) +#ifdef illumos case REG_RFL: return (rp->r_rfl); #endif case REG_RSP: return (rp->r_rsp); diff --git a/sys/cddl/dev/dtrace/amd64/instr_size.c b/sys/cddl/dev/dtrace/amd64/instr_size.c index 1acf2c5..b3afcb7 100644 --- a/sys/cddl/dev/dtrace/amd64/instr_size.c +++ b/sys/cddl/dev/dtrace/amd64/instr_size.c @@ -30,14 +30,14 @@ /* All Rights Reserved */ -#if defined(sun) +#ifdef illumos #pragma ident "@(#)instr_size.c 1.14 05/07/08 SMI" #endif #include <sys/types.h> #include <sys/param.h> #include <sys/proc.h> -#if defined(sun) +#ifdef illumos #include <sys/cmn_err.h> #include <sys/archsystm.h> #include <sys/copyops.h> @@ -104,7 +104,7 @@ dtrace_dis_isize(uchar_t *instr, dis_isize_t which, model_t model, int *rmindex) dis86_t x; uint_t mode = SIZE64; -#if defined(sun) +#ifdef illumos mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32; #endif diff --git a/sys/cddl/dev/dtrace/dtrace_ioctl.c b/sys/cddl/dev/dtrace/dtrace_ioctl.c index e261091..ef9bed5 100644 --- a/sys/cddl/dev/dtrace/dtrace_ioctl.c +++ b/sys/cddl/dev/dtrace/dtrace_ioctl.c @@ -578,14 +578,14 @@ dtrace_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, return (EINVAL); mutex_enter(&dtrace_provider_lock); -#if defined(sun) +#ifdef illumos mutex_enter(&mod_lock); #endif mutex_enter(&dtrace_lock); if (desc->dtargd_id > dtrace_nprobes) { mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -594,7 +594,7 @@ dtrace_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, if ((probe = dtrace_probes[desc->dtargd_id - 1]) == NULL) { mutex_exit(&dtrace_lock); -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -620,7 +620,7 @@ dtrace_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, probe->dtpr_id, probe->dtpr_arg, desc); } -#if defined(sun) +#ifdef illumos mutex_exit(&mod_lock); #endif mutex_exit(&dtrace_provider_lock); @@ -779,7 +779,7 @@ dtrace_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, dstate = &state->dts_vstate.dtvs_dynvars; for (i = 0; i < NCPU; i++) { -#if !defined(sun) +#ifndef illumos if (pcpu_find(i) == NULL) continue; #endif diff --git a/sys/cddl/dev/dtrace/i386/instr_size.c b/sys/cddl/dev/dtrace/i386/instr_size.c index 7f667f7..11fbf9b 100644 --- a/sys/cddl/dev/dtrace/i386/instr_size.c +++ b/sys/cddl/dev/dtrace/i386/instr_size.c @@ -30,14 +30,14 @@ /* All Rights Reserved */ -#if defined(sun) +#ifdef illumos #pragma ident "@(#)instr_size.c 1.14 05/07/08 SMI" #endif #include <sys/types.h> #include <sys/param.h> #include <sys/proc.h> -#if defined(sun) +#ifdef illumos #include <sys/cmn_err.h> #include <sys/archsystm.h> #include <sys/copyops.h> @@ -104,7 +104,7 @@ dtrace_dis_isize(uchar_t *instr, dis_isize_t which, model_t model, int *rmindex) dis86_t x; uint_t mode = SIZE32; -#if defined(sun) +#ifdef illumos mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32; #endif diff --git a/sys/cddl/dev/dtrace/x86/regset.h b/sys/cddl/dev/dtrace/x86/regset.h index b1c5116..ad12e26 100644 --- a/sys/cddl/dev/dtrace/x86/regset.h +++ b/sys/cddl/dev/dtrace/x86/regset.h @@ -61,7 +61,7 @@ extern "C" { #define REG_GSBASE 27 #define REG_FSBASE 26 -#if defined(sun) +#ifdef illumos #define REG_DS 25 #define REG_ES 24 @@ -89,7 +89,7 @@ extern "C" { #define REG_R13 2 #define REG_R14 1 #define REG_R15 0 -#else +#else /* !illumos */ #define REG_SS 25 #define REG_RSP 24 #define REG_RFL 23 @@ -116,13 +116,13 @@ extern "C" { #define REG_R13 2 #define REG_R14 1 #define REG_R15 0 -#endif +#endif /* illumos */ /* * The names and offsets defined here are specified by i386 ABI suppl. */ -#if defined(sun) +#ifdef illumos #define SS 18 /* only stored on a privilege transition */ #define UESP 17 /* only stored on a privilege transition */ #define EFL 16 @@ -142,7 +142,7 @@ extern "C" { #define ES 2 #define FS 1 #define GS 0 -#else +#else /* !illumos */ #define GS 18 #define SS 17 /* only stored on a privilege transition */ #define UESP 16 /* only stored on a privilege transition */ @@ -162,7 +162,7 @@ extern "C" { #define DS 2 #define ES 1 #define FS 0 -#endif +#endif /* illumos */ #define REG_PC EIP #define REG_FP EBP |