diff options
Diffstat (limited to 'sys/cddl/contrib/opensolaris')
9 files changed, 206 insertions, 92 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index 7ec7dfd..0012975 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -117,6 +117,7 @@ #include <sys/ctype.h> #include <sys/eventhandler.h> #include <sys/limits.h> +#include <sys/linker.h> #include <sys/kdb.h> #include <sys/kernel.h> #include <sys/malloc.h> @@ -11916,6 +11917,21 @@ dtrace_buffer_activate(dtrace_state_t *state) dtrace_interrupt_enable(cookie); } +#ifdef __FreeBSD__ +/* + * Activate the specified per-CPU buffer. This is used instead of + * dtrace_buffer_activate() when APs have not yet started, i.e. when + * activating anonymous state. + */ +static void +dtrace_buffer_activate_cpu(dtrace_state_t *state, int cpu) +{ + + if (state->dts_buffer[cpu].dtb_tomax != NULL) + state->dts_buffer[cpu].dtb_flags &= ~DTRACEBUF_INACTIVE; +} +#endif + static int dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags, processorid_t cpu, int *factor) @@ -12532,9 +12548,15 @@ dtrace_enabling_dump(dtrace_enabling_t *enab) for (i = 0; i < enab->dten_ndesc; i++) { dtrace_probedesc_t *desc = &enab->dten_desc[i]->dted_probe; +#ifdef __FreeBSD__ + printf("dtrace: enabling probe %d (%s:%s:%s:%s)\n", i, + desc->dtpd_provider, desc->dtpd_mod, + desc->dtpd_func, desc->dtpd_name); +#else cmn_err(CE_NOTE, "enabling probe %d (%s:%s:%s:%s)", i, desc->dtpd_provider, desc->dtpd_mod, desc->dtpd_func, desc->dtpd_name); +#endif } } @@ -13185,19 +13207,91 @@ dtrace_dof_char(char c) return (c - 'a' + 10); } /* Should not reach here. */ - return (0); + return (UCHAR_MAX); } #endif /* __FreeBSD__ */ static dof_hdr_t * dtrace_dof_property(const char *name) { +#ifdef __FreeBSD__ + uint8_t *dofbuf; + u_char *data, *eol; + caddr_t doffile; + size_t bytes, len, i; + dof_hdr_t *dof; + u_char c1, c2; + + dof = NULL; + + doffile = preload_search_by_type("dtrace_dof"); + if (doffile == NULL) + return (NULL); + + data = preload_fetch_addr(doffile); + len = preload_fetch_size(doffile); + for (;;) { + /* Look for the end of the line. All lines end in a newline. */ + eol = memchr(data, '\n', len); + if (eol == NULL) + return (NULL); + + if (strncmp(name, data, strlen(name)) == 0) + break; + + eol++; /* skip past the newline */ + len -= eol - data; + data = eol; + } + + /* We've found the data corresponding to the specified key. */ + + data += strlen(name) + 1; /* skip past the '=' */ + len = eol - data; + bytes = len / 2; + + if (bytes < sizeof(dof_hdr_t)) { + dtrace_dof_error(NULL, "truncated header"); + goto doferr; + } + + /* + * Each byte is represented by the two ASCII characters in its hex + * representation. + */ + dofbuf = malloc(bytes, M_SOLARIS, M_WAITOK); + for (i = 0; i < bytes; i++) { + c1 = dtrace_dof_char(data[i * 2]); + c2 = dtrace_dof_char(data[i * 2 + 1]); + if (c1 == UCHAR_MAX || c2 == UCHAR_MAX) { + dtrace_dof_error(NULL, "invalid hex char in DOF"); + goto doferr; + } + dofbuf[i] = c1 * 16 + c2; + } + + dof = (dof_hdr_t *)dofbuf; + if (bytes < dof->dofh_loadsz) { + dtrace_dof_error(NULL, "truncated DOF"); + goto doferr; + } + + if (dof->dofh_loadsz >= dtrace_dof_maxsize) { + dtrace_dof_error(NULL, "oversized DOF"); + goto doferr; + } + + return (dof); + +doferr: + free(dof, M_SOLARIS); + return (NULL); +#else /* __FreeBSD__ */ uchar_t *buf; uint64_t loadsz; unsigned int len, i; dof_hdr_t *dof; -#ifdef illumos /* * Unfortunately, array of values in .conf files are always (and * only) interpreted to be integer arrays. We must read our DOF @@ -13231,49 +13325,9 @@ dtrace_dof_property(const char *name) dof = kmem_alloc(loadsz, KM_SLEEP); bcopy(buf, dof, loadsz); ddi_prop_free(buf); -#else - char *p; - char *p_env; - - if ((p_env = kern_getenv(name)) == NULL) - return (NULL); - - len = strlen(p_env) / 2; - - buf = kmem_alloc(len, KM_SLEEP); - - dof = (dof_hdr_t *) buf; - - p = p_env; - - for (i = 0; i < len; i++) { - buf[i] = (dtrace_dof_char(p[0]) << 4) | - dtrace_dof_char(p[1]); - p += 2; - } - - freeenv(p_env); - - if (len < sizeof (dof_hdr_t)) { - kmem_free(buf, 0); - dtrace_dof_error(NULL, "truncated header"); - return (NULL); - } - - if (len < (loadsz = dof->dofh_loadsz)) { - kmem_free(buf, 0); - dtrace_dof_error(NULL, "truncated DOF"); - return (NULL); - } - - if (loadsz >= dtrace_dof_maxsize) { - kmem_free(buf, 0); - dtrace_dof_error(NULL, "oversized DOF"); - return (NULL); - } -#endif return (dof); +#endif /* !__FreeBSD__ */ } static void @@ -14332,7 +14386,7 @@ static dtrace_state_t * #ifdef illumos dtrace_state_create(dev_t *devp, cred_t *cr) #else -dtrace_state_create(struct cdev *dev) +dtrace_state_create(struct cdev *dev, struct ucred *cred __unused) #endif { #ifdef illumos @@ -14945,6 +14999,18 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) if (state->dts_activity == DTRACE_ACTIVITY_WARMUP) state->dts_activity = DTRACE_ACTIVITY_ACTIVE; +#ifdef __FreeBSD__ + /* + * We enable anonymous tracing before APs are started, so we must + * activate buffers using the current CPU. + */ + if (state == dtrace_anon.dta_state) + for (int i = 0; i < NCPU; i++) + dtrace_buffer_activate_cpu(state, i); + else + dtrace_xcall(DTRACE_CPUALL, + (dtrace_xcall_t)dtrace_buffer_activate, state); +#else /* * Regardless of whether or not now we're in ACTIVE or DRAINING, we * want each CPU to transition its principal buffer out of the @@ -14955,6 +15021,7 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) */ dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_buffer_activate, state); +#endif goto out; err: @@ -15316,11 +15383,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) { -#ifdef illumos state = dtrace_state_create(NULL, NULL); -#else - state = dtrace_state_create(NULL); -#endif dtrace_anon.dta_state = state; if (state == NULL) { @@ -17001,7 +17064,7 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) state = dtrace_state_create(devp, cred_p); #else - state = dtrace_state_create(dev); + state = dtrace_state_create(dev, NULL); devfs_set_cdevpriv(state, dtrace_dtr); #endif 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 f944903..534dfb2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -132,6 +132,7 @@ #include <sys/multilist.h> #ifdef _KERNEL #include <sys/dnlc.h> +#include <sys/racct.h> #endif #include <sys/callb.h> #include <sys/kstat.h> @@ -4503,6 +4504,14 @@ top: demand, prefetch, !HDR_ISTYPE_METADATA(hdr), data, metadata, misses); #ifdef _KERNEL +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(curproc); + racct_add_force(curproc, RACCT_READBPS, size); + racct_add_force(curproc, RACCT_READIOPS, 1); + PROC_UNLOCK(curproc); + } +#endif /* RACCT */ curthread->td_ru.ru_inblock++; #endif 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 b60236f..af8d366 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -47,6 +47,7 @@ #include <sys/sa.h> #include <sys/zfeature.h> #ifdef _KERNEL +#include <sys/racct.h> #include <sys/vm.h> #include <sys/zfs_znode.h> #endif @@ -427,6 +428,15 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length, } dbp = kmem_zalloc(sizeof (dmu_buf_t *) * nblks, KM_SLEEP); +#if defined(_KERNEL) && defined(RACCT) + if (racct_enable && !read) { + PROC_LOCK(curproc); + racct_add_force(curproc, RACCT_WRITEBPS, length); + racct_add_force(curproc, RACCT_WRITEIOPS, nblks); + PROC_UNLOCK(curproc); + } +#endif + zio = zio_root(dn->dn_objset->os_spa, NULL, NULL, ZIO_FLAG_CANFAIL); blkid = dbuf_whichblock(dn, 0, offset); for (i = 0; i < nblks; i++) { @@ -1422,7 +1432,15 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf, DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA) { #ifdef _KERNEL curthread->td_ru.ru_oublock++; -#endif +#ifdef RACCT + if (racct_enable) { + PROC_LOCK(curproc); + racct_add_force(curproc, RACCT_WRITEBPS, blksz); + racct_add_force(curproc, RACCT_WRITEIOPS, 1); + PROC_UNLOCK(curproc); + } +#endif /* RACCT */ +#endif /* _KERNEL */ dbuf_assign_arcbuf(db, buf, tx); dbuf_rele(db, FTAG); } else { 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 30a0710..95e741f 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 @@ -48,7 +48,7 @@ #include <sys/zil_impl.h> #include <sys/dsl_userhold.h> -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && defined(_KERNEL) #include <sys/sysctl.h> #include <sys/types.h> #endif @@ -132,7 +132,7 @@ int zfs_delay_min_dirty_percent = 60; uint64_t zfs_delay_scale = 1000 * 1000 * 1000 / 2000; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && defined(_KERNEL) extern int zfs_vdev_async_write_active_max_dirty_percent; 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 f69a5e7..2e039ed 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -929,7 +929,7 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) * than the other taskqs. */ if (t == ZIO_TYPE_WRITE && q == ZIO_TASKQ_ISSUE) - pri--; + pri++; tq = taskq_create_proc(name, value, pri, 50, INT_MAX, spa->spa_proc, flags); 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 6080594..63350b3 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 @@ -55,6 +55,11 @@ #include "zfs_prop.h" #include <sys/zfeature.h> +#if defined(__FreeBSD__) && defined(_KERNEL) +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + /* * SPA locking * @@ -255,35 +260,6 @@ int zfs_flags = 0; * in leaked space, or worse. */ boolean_t zfs_recover = B_FALSE; -SYSCTL_DECL(_vfs_zfs); -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); -} -SYSCTL_PROC(_vfs_zfs, OID_AUTO, debug_flags, - CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RWTUN, 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 @@ -325,26 +301,18 @@ boolean_t zfs_free_leak_on_eio = B_FALSE; * in a system panic. */ uint64_t zfs_deadman_synctime_ms = 1000000ULL; -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, deadman_synctime_ms, CTLFLAG_RDTUN, - &zfs_deadman_synctime_ms, 0, - "Stalled ZFS I/O expiration time in milliseconds"); /* * Check time in milliseconds. This defines the frequency at which we check * for hung I/O. */ uint64_t zfs_deadman_checktime_ms = 5000ULL; -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, deadman_checktime_ms, CTLFLAG_RDTUN, - &zfs_deadman_checktime_ms, 0, - "Period of checks for stalled ZFS I/O in milliseconds"); /* * Default value of -1 for zfs_deadman_enabled is resolved in * zfs_deadman_init() */ int zfs_deadman_enabled = -1; -SYSCTL_INT(_vfs_zfs, OID_AUTO, deadman_enabled, CTLFLAG_RDTUN, - &zfs_deadman_enabled, 0, "Kernel panic on stalled ZFS I/O"); /* * The worst case is single-sector max-parity RAID-Z blocks, in which @@ -356,8 +324,50 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, deadman_enabled, CTLFLAG_RDTUN, * (VDEV_RAIDZ_MAXPARITY + 1) * SPA_DVAS_PER_BP * 2 == 24 */ int spa_asize_inflation = 24; + +#if defined(__FreeBSD__) && defined(_KERNEL) +SYSCTL_DECL(_vfs_zfs); +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); +} + +SYSCTL_PROC(_vfs_zfs, OID_AUTO, debug_flags, + CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RWTUN, 0, sizeof(int), + sysctl_vfs_zfs_debug_flags, "IU", "Debug flags for ZFS testing."); + +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, deadman_synctime_ms, CTLFLAG_RDTUN, + &zfs_deadman_synctime_ms, 0, + "Stalled ZFS I/O expiration time in milliseconds"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, deadman_checktime_ms, CTLFLAG_RDTUN, + &zfs_deadman_checktime_ms, 0, + "Period of checks for stalled ZFS I/O in milliseconds"); +SYSCTL_INT(_vfs_zfs, OID_AUTO, deadman_enabled, CTLFLAG_RDTUN, + &zfs_deadman_enabled, 0, "Kernel panic on stalled ZFS I/O"); SYSCTL_INT(_vfs_zfs, OID_AUTO, spa_asize_inflation, CTLFLAG_RWTUN, &spa_asize_inflation, 0, "Worst case inflation factor for single sector writes"); +#endif #ifndef illumos #ifdef _KERNEL 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 1fd9623..f459655 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 @@ -679,7 +679,15 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) g_topology_unlock(); vdev_geom_read_guids(cp, &pguid, &vguid); g_topology_lock(); - if (pguid != spa_guid(vd->vdev_spa) || + /* + * Check that the label's vdev guid matches the + * desired guid. If the label has a pool guid, + * check that it matches too. (Inactive spares + * and L2ARCs do not have any pool guid in the + * label.) + */ + if ((pguid != 0 && + pguid != spa_guid(vd->vdev_spa)) || vguid != vd->vdev_guid) { vdev_geom_close_locked(vd); cp = NULL; 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 05e16ba..6dc0ad3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -128,11 +128,13 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, sync_pass_rewrite, CTLFLAG_RDTUN, boolean_t zio_requeue_io_start_cut_in_line = B_TRUE; +#ifdef illumos #ifdef ZFS_DEBUG int zio_buf_debug_limit = 16384; #else int zio_buf_debug_limit = 0; #endif +#endif void zio_init(void) @@ -154,7 +156,7 @@ zio_init(void) size_t size = (c + 1) << SPA_MINBLOCKSHIFT; size_t p2 = size; size_t align = 0; - size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0; + int cflags = zio_exclude_metadata ? KMC_NODEBUG : 0; while (!ISP2(p2)) p2 &= p2 - 1; 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 3818616..7c25ddd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -785,6 +785,10 @@ typedef struct ddt_histogram { #define ZFS_DRIVER "zfs" #define ZFS_DEV_NAME "zfs" #define ZFS_DEV "/dev/" ZFS_DEV_NAME +#define ZFS_DISK_ROOT "/dev/dsk" +#define ZFS_DISK_ROOTD ZFS_DISK_ROOT "/" +#define ZFS_RDISK_ROOT "/dev/rdsk" +#define ZFS_RDISK_ROOTD ZFS_RDISK_ROOT "/" /* general zvol path */ #define ZVOL_DIR "/dev/zvol" |