8809 libzpool should leverage work done in libfakekernel
illumos/illumos-gate@f06dce2c1f Reviewed by: Sebastien Roy <sebastien.roy@delphix.com> Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: Gordon Ross <gordon.w.ross@gmail.com> Approved by: Richard Lowe <richlowe@richlowe.net> Author: Andrew Stormont <astormont@racktopsystems.com>
This commit is contained in:
parent
ed2ac05a27
commit
81ef5e369c
@ -24,6 +24,7 @@
|
||||
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2017 Nexenta Systems, Inc.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -87,11 +88,13 @@ extern int reference_tracking_enable;
|
||||
extern boolean_t zfs_recover;
|
||||
extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
|
||||
extern int zfs_vdev_async_read_max_active;
|
||||
extern int aok;
|
||||
#else
|
||||
int reference_tracking_enable;
|
||||
boolean_t zfs_recover;
|
||||
uint64_t zfs_arc_max, zfs_arc_meta_limit;
|
||||
int zfs_vdev_async_read_max_active;
|
||||
int aok;
|
||||
#endif
|
||||
|
||||
static const char cmdname[] = "zdb";
|
||||
|
@ -25,6 +25,7 @@
|
||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2017 Joyent, Inc.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -245,8 +246,8 @@ typedef enum {
|
||||
typedef struct rll {
|
||||
void *rll_writer;
|
||||
int rll_readers;
|
||||
mutex_t rll_lock;
|
||||
cond_t rll_cv;
|
||||
kmutex_t rll_lock;
|
||||
kcondvar_t rll_cv;
|
||||
} rll_t;
|
||||
|
||||
typedef struct rl {
|
||||
@ -280,11 +281,11 @@ typedef struct ztest_od {
|
||||
typedef struct ztest_ds {
|
||||
ztest_shared_ds_t *zd_shared;
|
||||
objset_t *zd_os;
|
||||
rwlock_t zd_zilog_lock;
|
||||
krwlock_t zd_zilog_lock;
|
||||
zilog_t *zd_zilog;
|
||||
ztest_od_t *zd_od; /* debugging aid */
|
||||
char zd_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||
mutex_t zd_dirobj_lock;
|
||||
kmutex_t zd_dirobj_lock;
|
||||
rll_t zd_object_lock[ZTEST_OBJECT_LOCKS];
|
||||
rll_t zd_range_lock[ZTEST_RANGE_LOCKS];
|
||||
} ztest_ds_t;
|
||||
@ -395,7 +396,7 @@ ztest_info_t ztest_info[] = {
|
||||
* The callbacks are ordered by txg number.
|
||||
*/
|
||||
typedef struct ztest_cb_list {
|
||||
mutex_t zcl_callbacks_lock;
|
||||
kmutex_t zcl_callbacks_lock;
|
||||
list_t zcl_callbacks;
|
||||
} ztest_cb_list_t;
|
||||
|
||||
@ -430,7 +431,7 @@ ztest_shared_t *ztest_shared;
|
||||
static spa_t *ztest_spa = NULL;
|
||||
static ztest_ds_t *ztest_ds;
|
||||
|
||||
static mutex_t ztest_vdev_lock;
|
||||
static kmutex_t ztest_vdev_lock;
|
||||
|
||||
/*
|
||||
* The ztest_name_lock protects the pool and dataset namespace used by
|
||||
@ -438,7 +439,7 @@ static mutex_t ztest_vdev_lock;
|
||||
* this lock as writer. Grabbing the lock as reader will ensure that the
|
||||
* namespace does not change while the lock is held.
|
||||
*/
|
||||
static rwlock_t ztest_name_lock;
|
||||
static krwlock_t ztest_name_lock;
|
||||
|
||||
static boolean_t ztest_dump_core = B_TRUE;
|
||||
static boolean_t ztest_exiting;
|
||||
@ -1094,8 +1095,8 @@ ztest_rll_init(rll_t *rll)
|
||||
{
|
||||
rll->rll_writer = NULL;
|
||||
rll->rll_readers = 0;
|
||||
VERIFY(_mutex_init(&rll->rll_lock, USYNC_THREAD, NULL) == 0);
|
||||
VERIFY(cond_init(&rll->rll_cv, USYNC_THREAD, NULL) == 0);
|
||||
mutex_init(&rll->rll_lock, NULL, USYNC_THREAD, NULL);
|
||||
cv_init(&rll->rll_cv, NULL, USYNC_THREAD, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1103,32 +1104,32 @@ ztest_rll_destroy(rll_t *rll)
|
||||
{
|
||||
ASSERT(rll->rll_writer == NULL);
|
||||
ASSERT(rll->rll_readers == 0);
|
||||
VERIFY(_mutex_destroy(&rll->rll_lock) == 0);
|
||||
VERIFY(cond_destroy(&rll->rll_cv) == 0);
|
||||
mutex_destroy(&rll->rll_lock);
|
||||
cv_destroy(&rll->rll_cv);
|
||||
}
|
||||
|
||||
static void
|
||||
ztest_rll_lock(rll_t *rll, rl_type_t type)
|
||||
{
|
||||
VERIFY(mutex_lock(&rll->rll_lock) == 0);
|
||||
mutex_enter(&rll->rll_lock);
|
||||
|
||||
if (type == RL_READER) {
|
||||
while (rll->rll_writer != NULL)
|
||||
(void) cond_wait(&rll->rll_cv, &rll->rll_lock);
|
||||
cv_wait(&rll->rll_cv, &rll->rll_lock);
|
||||
rll->rll_readers++;
|
||||
} else {
|
||||
while (rll->rll_writer != NULL || rll->rll_readers)
|
||||
(void) cond_wait(&rll->rll_cv, &rll->rll_lock);
|
||||
cv_wait(&rll->rll_cv, &rll->rll_lock);
|
||||
rll->rll_writer = curthread;
|
||||
}
|
||||
|
||||
VERIFY(mutex_unlock(&rll->rll_lock) == 0);
|
||||
mutex_exit(&rll->rll_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
ztest_rll_unlock(rll_t *rll)
|
||||
{
|
||||
VERIFY(mutex_lock(&rll->rll_lock) == 0);
|
||||
mutex_enter(&rll->rll_lock);
|
||||
|
||||
if (rll->rll_writer) {
|
||||
ASSERT(rll->rll_readers == 0);
|
||||
@ -1140,9 +1141,9 @@ ztest_rll_unlock(rll_t *rll)
|
||||
}
|
||||
|
||||
if (rll->rll_writer == NULL && rll->rll_readers == 0)
|
||||
VERIFY(cond_broadcast(&rll->rll_cv) == 0);
|
||||
cv_broadcast(&rll->rll_cv);
|
||||
|
||||
VERIFY(mutex_unlock(&rll->rll_lock) == 0);
|
||||
mutex_exit(&rll->rll_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1201,8 +1202,8 @@ ztest_zd_init(ztest_ds_t *zd, ztest_shared_ds_t *szd, objset_t *os)
|
||||
if (zd->zd_shared != NULL)
|
||||
zd->zd_shared->zd_seq = 0;
|
||||
|
||||
VERIFY(rwlock_init(&zd->zd_zilog_lock, USYNC_THREAD, NULL) == 0);
|
||||
VERIFY(_mutex_init(&zd->zd_dirobj_lock, USYNC_THREAD, NULL) == 0);
|
||||
rw_init(&zd->zd_zilog_lock, NULL, USYNC_THREAD, NULL);
|
||||
mutex_init(&zd->zd_dirobj_lock, NULL, USYNC_THREAD, NULL);
|
||||
|
||||
for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
|
||||
ztest_rll_init(&zd->zd_object_lock[l]);
|
||||
@ -1214,7 +1215,7 @@ ztest_zd_init(ztest_ds_t *zd, ztest_shared_ds_t *szd, objset_t *os)
|
||||
static void
|
||||
ztest_zd_fini(ztest_ds_t *zd)
|
||||
{
|
||||
VERIFY(_mutex_destroy(&zd->zd_dirobj_lock) == 0);
|
||||
mutex_destroy(&zd->zd_dirobj_lock);
|
||||
|
||||
for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
|
||||
ztest_rll_destroy(&zd->zd_object_lock[l]);
|
||||
@ -1969,7 +1970,7 @@ ztest_lookup(ztest_ds_t *zd, ztest_od_t *od, int count)
|
||||
int missing = 0;
|
||||
int error;
|
||||
|
||||
ASSERT(_mutex_held(&zd->zd_dirobj_lock));
|
||||
ASSERT(MUTEX_HELD(&zd->zd_dirobj_lock));
|
||||
|
||||
for (int i = 0; i < count; i++, od++) {
|
||||
od->od_object = 0;
|
||||
@ -2009,7 +2010,7 @@ ztest_create(ztest_ds_t *zd, ztest_od_t *od, int count)
|
||||
{
|
||||
int missing = 0;
|
||||
|
||||
ASSERT(_mutex_held(&zd->zd_dirobj_lock));
|
||||
ASSERT(MUTEX_HELD(&zd->zd_dirobj_lock));
|
||||
|
||||
for (int i = 0; i < count; i++, od++) {
|
||||
if (missing) {
|
||||
@ -2054,7 +2055,7 @@ ztest_remove(ztest_ds_t *zd, ztest_od_t *od, int count)
|
||||
int missing = 0;
|
||||
int error;
|
||||
|
||||
ASSERT(_mutex_held(&zd->zd_dirobj_lock));
|
||||
ASSERT(MUTEX_HELD(&zd->zd_dirobj_lock));
|
||||
|
||||
od += count - 1;
|
||||
|
||||
@ -2200,7 +2201,7 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
|
||||
if (ztest_random(2) == 0)
|
||||
io_type = ZTEST_IO_WRITE_TAG;
|
||||
|
||||
(void) rw_rdlock(&zd->zd_zilog_lock);
|
||||
rw_enter(&zd->zd_zilog_lock, RW_READER);
|
||||
|
||||
switch (io_type) {
|
||||
|
||||
@ -2237,7 +2238,7 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
|
||||
break;
|
||||
|
||||
case ZTEST_IO_REWRITE:
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
err = ztest_dsl_prop_set_uint64(zd->zd_name,
|
||||
ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
|
||||
B_FALSE);
|
||||
@ -2247,7 +2248,7 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
|
||||
ztest_random_dsl_prop(ZFS_PROP_COMPRESSION),
|
||||
B_FALSE);
|
||||
VERIFY(err == 0 || err == ENOSPC);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
|
||||
DMU_READ_NO_PREFETCH));
|
||||
@ -2256,7 +2257,7 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
|
||||
break;
|
||||
}
|
||||
|
||||
(void) rw_unlock(&zd->zd_zilog_lock);
|
||||
rw_exit(&zd->zd_zilog_lock);
|
||||
|
||||
umem_free(data, blocksize);
|
||||
}
|
||||
@ -2295,13 +2296,13 @@ ztest_object_init(ztest_ds_t *zd, ztest_od_t *od, size_t size, boolean_t remove)
|
||||
int count = size / sizeof (*od);
|
||||
int rv = 0;
|
||||
|
||||
VERIFY(mutex_lock(&zd->zd_dirobj_lock) == 0);
|
||||
mutex_enter(&zd->zd_dirobj_lock);
|
||||
if ((ztest_lookup(zd, od, count) != 0 || remove) &&
|
||||
(ztest_remove(zd, od, count) != 0 ||
|
||||
ztest_create(zd, od, count) != 0))
|
||||
rv = -1;
|
||||
zd->zd_od = od;
|
||||
VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
|
||||
mutex_exit(&zd->zd_dirobj_lock);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
@ -2312,7 +2313,7 @@ ztest_zil_commit(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
zilog_t *zilog = zd->zd_zilog;
|
||||
|
||||
(void) rw_rdlock(&zd->zd_zilog_lock);
|
||||
rw_enter(&zd->zd_zilog_lock, RW_READER);
|
||||
|
||||
zil_commit(zilog, ztest_random(ZTEST_OBJECTS));
|
||||
|
||||
@ -2327,7 +2328,7 @@ ztest_zil_commit(ztest_ds_t *zd, uint64_t id)
|
||||
zd->zd_shared->zd_seq = zilog->zl_commit_lr_seq;
|
||||
mutex_exit(&zilog->zl_lock);
|
||||
|
||||
(void) rw_unlock(&zd->zd_zilog_lock);
|
||||
rw_exit(&zd->zd_zilog_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2346,8 +2347,8 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
|
||||
* updating the zil (i.e. adding in-memory log records) and the
|
||||
* zd_zilog_lock to block any I/O.
|
||||
*/
|
||||
VERIFY0(mutex_lock(&zd->zd_dirobj_lock));
|
||||
(void) rw_wrlock(&zd->zd_zilog_lock);
|
||||
mutex_enter(&zd->zd_dirobj_lock);
|
||||
rw_enter(&zd->zd_zilog_lock, RW_WRITER);
|
||||
|
||||
/* zfsvfs_teardown() */
|
||||
zil_close(zd->zd_zilog);
|
||||
@ -2356,8 +2357,8 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
|
||||
VERIFY(zil_open(os, ztest_get_data) == zd->zd_zilog);
|
||||
zil_replay(os, zd, ztest_replay_vector);
|
||||
|
||||
(void) rw_unlock(&zd->zd_zilog_lock);
|
||||
VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
|
||||
rw_exit(&zd->zd_zilog_lock);
|
||||
mutex_exit(&zd->zd_dirobj_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2392,7 +2393,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
* Attempt to create an existing pool. It shouldn't matter
|
||||
* what's in the nvroot; we should fail with EEXIST.
|
||||
*/
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
|
||||
VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL));
|
||||
nvlist_free(nvroot);
|
||||
@ -2400,7 +2401,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
VERIFY3U(EBUSY, ==, spa_destroy(zo->zo_pool));
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -2413,7 +2414,7 @@ ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
|
||||
nvlist_t *nvroot, *props;
|
||||
char *name;
|
||||
|
||||
VERIFY0(mutex_lock(&ztest_vdev_lock));
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
name = kmem_asprintf("%s_upgrade", ztest_opts.zo_pool);
|
||||
|
||||
/*
|
||||
@ -2472,7 +2473,7 @@ ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
strfree(name);
|
||||
VERIFY0(mutex_unlock(&ztest_vdev_lock));
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
static vdev_t *
|
||||
@ -2525,7 +2526,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
|
||||
nvlist_t *nvroot;
|
||||
int error;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
|
||||
|
||||
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
||||
@ -2551,9 +2552,9 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
|
||||
* dmu_objset_destroy() to fail with EBUSY thus
|
||||
* leaving the dataset in an inconsistent state.
|
||||
*/
|
||||
VERIFY(rw_wrlock(&ztest_name_lock) == 0);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
error = spa_vdev_remove(spa, guid, B_FALSE);
|
||||
VERIFY(rw_unlock(&ztest_name_lock) == 0);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
if (error && error != EEXIST)
|
||||
fatal(0, "spa_vdev_remove() = %d", error);
|
||||
@ -2577,7 +2578,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(0, "spa_vdev_add() = %d", error);
|
||||
}
|
||||
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2603,7 +2604,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
|
||||
aux = ZPOOL_CONFIG_L2CACHE;
|
||||
}
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
|
||||
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
||||
|
||||
@ -2660,7 +2661,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(0, "spa_vdev_remove(%llu) = %d", guid, error);
|
||||
}
|
||||
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2677,11 +2678,11 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
|
||||
uint_t c, children, schildren = 0, lastlogid = 0;
|
||||
int error = 0;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
|
||||
/* ensure we have a useable config; mirrors of raidz aren't supported */
|
||||
if (zs->zs_mirrors < 3 || ztest_opts.zo_raidz > 1) {
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2740,9 +2741,9 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
spa_config_exit(spa, SCL_VDEV, FTAG);
|
||||
|
||||
(void) rw_wrlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
error = spa_vdev_split_mirror(spa, "splitp", config, NULL, B_FALSE);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
nvlist_free(config);
|
||||
|
||||
@ -2755,7 +2756,7 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
|
||||
++zs->zs_splits;
|
||||
--zs->zs_mirrors;
|
||||
}
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
|
||||
}
|
||||
|
||||
@ -2784,7 +2785,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
int oldvd_is_log;
|
||||
int error, expected_error;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
|
||||
|
||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
||||
@ -2797,7 +2798,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
*/
|
||||
if (spa->spa_vdev_removal != NULL) {
|
||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2857,7 +2858,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
if (error != 0 && error != ENODEV && error != EBUSY &&
|
||||
error != ENOTSUP)
|
||||
fatal(0, "detach (%s) returned %d", oldpath, error);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2955,7 +2956,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
newsize, replacing, error, expected_error);
|
||||
}
|
||||
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -2966,7 +2967,7 @@ ztest_device_removal(ztest_ds_t *zd, uint64_t id)
|
||||
vdev_t *vd;
|
||||
uint64_t guid;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
|
||||
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
||||
vd = vdev_lookup_top(spa, ztest_random_vdev_top(spa, B_FALSE));
|
||||
@ -2975,7 +2976,7 @@ ztest_device_removal(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
(void) spa_vdev_remove(spa, guid, B_FALSE);
|
||||
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3103,7 +3104,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
uint64_t top;
|
||||
uint64_t old_class_space, new_class_space, old_ms_count, new_ms_count;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
spa_config_enter(spa, SCL_STATE, spa, RW_READER);
|
||||
|
||||
/*
|
||||
@ -3114,7 +3115,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
*/
|
||||
if (spa->spa_vdev_removal != NULL) {
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3143,7 +3144,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
if (tvd->vdev_state != VDEV_STATE_HEALTHY ||
|
||||
psize == 0 || psize >= 4 * ztest_opts.zo_vdev_size) {
|
||||
spa_config_exit(spa, SCL_STATE, spa);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
ASSERT(psize > 0);
|
||||
@ -3168,7 +3169,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
"the vdev configuration changed.\n");
|
||||
}
|
||||
spa_config_exit(spa, SCL_STATE, spa);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3202,7 +3203,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
"intervening vdev offline or remove.\n");
|
||||
}
|
||||
spa_config_exit(spa, SCL_STATE, spa);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3232,7 +3233,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
|
||||
}
|
||||
|
||||
spa_config_exit(spa, SCL_STATE, spa);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3343,7 +3344,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
char name[ZFS_MAX_DATASET_NAME_LEN];
|
||||
zilog_t *zilog;
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
(void) snprintf(name, sizeof (name), "%s/temp_%llu",
|
||||
ztest_opts.zo_pool, (u_longlong_t)id);
|
||||
@ -3382,7 +3383,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
return;
|
||||
}
|
||||
fatal(0, "dmu_objset_create(%s) = %d", name, error);
|
||||
@ -3430,7 +3431,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
dmu_objset_disown(os, FTAG);
|
||||
ztest_zd_fini(&zdtmp);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3439,10 +3440,10 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
void
|
||||
ztest_dmu_snapshot_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
(void) ztest_snapshot_destroy(zd->zd_name, id);
|
||||
(void) ztest_snapshot_create(zd->zd_name, id);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3501,7 +3502,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
char *osname = zd->zd_name;
|
||||
int error;
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
ztest_dsl_dataset_cleanup(osname, id);
|
||||
|
||||
@ -3578,7 +3579,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
out:
|
||||
ztest_dsl_dataset_cleanup(osname, id);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4512,9 +4513,9 @@ ztest_commit_callback(void *arg, int error)
|
||||
ASSERT3U(data->zcd_txg, !=, 0);
|
||||
|
||||
/* Remove our callback from the list */
|
||||
(void) mutex_lock(&zcl.zcl_callbacks_lock);
|
||||
mutex_enter(&zcl.zcl_callbacks_lock);
|
||||
list_remove(&zcl.zcl_callbacks, data);
|
||||
(void) mutex_unlock(&zcl.zcl_callbacks_lock);
|
||||
mutex_exit(&zcl.zcl_callbacks_lock);
|
||||
|
||||
out:
|
||||
umem_free(data, sizeof (ztest_cb_data_t));
|
||||
@ -4616,7 +4617,7 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
dmu_write(os, od[0].od_object, 0, sizeof (uint64_t), &txg, tx);
|
||||
|
||||
(void) mutex_lock(&zcl.zcl_callbacks_lock);
|
||||
mutex_enter(&zcl.zcl_callbacks_lock);
|
||||
|
||||
/*
|
||||
* Since commit callbacks don't have any ordering requirement and since
|
||||
@ -4663,7 +4664,7 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
|
||||
tmp_cb = cb_data[i];
|
||||
}
|
||||
|
||||
(void) mutex_unlock(&zcl.zcl_callbacks_lock);
|
||||
mutex_exit(&zcl.zcl_callbacks_lock);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
}
|
||||
@ -4679,27 +4680,27 @@ ztest_dsl_prop_get_set(ztest_ds_t *zd, uint64_t id)
|
||||
ZFS_PROP_DEDUP
|
||||
};
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
for (int p = 0; p < sizeof (proplist) / sizeof (proplist[0]); p++)
|
||||
(void) ztest_dsl_prop_set_uint64(zd->zd_name, proplist[p],
|
||||
ztest_random_dsl_prop(proplist[p]), (int)ztest_random(2));
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
ztest_remap_blocks(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
int error = dmu_objset_remap_indirects(zd->zd_name);
|
||||
if (error == ENOSPC)
|
||||
error = 0;
|
||||
ASSERT0(error);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -4708,7 +4709,7 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
nvlist_t *props = NULL;
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
(void) ztest_spa_prop_set_uint64(ZPOOL_PROP_DEDUPDITTO,
|
||||
ZIO_DEDUPDITTO_MIN + ztest_random(ZIO_DEDUPDITTO_MIN));
|
||||
@ -4720,7 +4721,7 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
nvlist_free(props);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4755,7 +4756,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
char osname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
nvlist_t *holds;
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
dmu_objset_name(os, osname);
|
||||
|
||||
@ -4860,7 +4861,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT);
|
||||
|
||||
out:
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4888,11 +4889,11 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
uint64_t guid0 = 0;
|
||||
boolean_t islog = B_FALSE;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
maxfaults = MAXFAULTS();
|
||||
leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
|
||||
mirror_save = zs->zs_mirrors;
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
|
||||
ASSERT(leaves >= 1);
|
||||
|
||||
@ -4902,7 +4903,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
* they are in progress (i.e. spa_change_guid). Those
|
||||
* operations will have grabbed the name lock as writer.
|
||||
*/
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
/*
|
||||
* We need SCL_STATE here because we're going to look at vd0->vdev_tsd.
|
||||
@ -4974,7 +4975,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
if (sav->sav_count == 0) {
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
return;
|
||||
}
|
||||
vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
|
||||
@ -4988,7 +4989,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
}
|
||||
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
/*
|
||||
* If we can tolerate two or more faults, or we're dealing
|
||||
@ -5008,12 +5009,12 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
* leaving the dataset in an inconsistent state.
|
||||
*/
|
||||
if (islog)
|
||||
(void) rw_wrlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
|
||||
VERIFY(vdev_offline(spa, guid0, flags) != EBUSY);
|
||||
|
||||
if (islog)
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
} else {
|
||||
/*
|
||||
* Ideally we would like to be able to randomly
|
||||
@ -5024,9 +5025,9 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
* prevent a race between injection testing and
|
||||
* aux_vdev removal.
|
||||
*/
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
(void) vdev_online(spa, guid0, 0, NULL);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5098,9 +5099,9 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
|
||||
continue;
|
||||
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
mutex_enter(&ztest_vdev_lock);
|
||||
if (mirror_save != zs->zs_mirrors) {
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
(void) close(fd);
|
||||
return;
|
||||
}
|
||||
@ -5109,7 +5110,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(1, "can't inject bad word at 0x%llx in %s",
|
||||
offset, pathrand);
|
||||
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
mutex_exit(&ztest_vdev_lock);
|
||||
|
||||
if (ztest_opts.zo_verbose >= 7)
|
||||
(void) printf("injected bad word into %s,"
|
||||
@ -5149,13 +5150,13 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
|
||||
* Take the name lock as writer to prevent anyone else from changing
|
||||
* the pool and dataset properies we need to maintain during this test.
|
||||
*/
|
||||
(void) rw_wrlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
|
||||
if (ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_DEDUP, checksum,
|
||||
B_FALSE) != 0 ||
|
||||
ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_COPIES, 1,
|
||||
B_FALSE) != 0) {
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5174,7 +5175,7 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
|
||||
dmu_tx_hold_write(tx, object, 0, copies * blocksize);
|
||||
txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
|
||||
if (txg == 0) {
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5222,7 +5223,7 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
abd_free(abd);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5253,9 +5254,9 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id)
|
||||
orig = spa_guid(spa);
|
||||
load = spa_load_guid(spa);
|
||||
|
||||
(void) rw_wrlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
error = spa_change_guid(spa);
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
if (error != 0)
|
||||
return;
|
||||
@ -5279,7 +5280,7 @@ ztest_spa_rename(ztest_ds_t *zd, uint64_t id)
|
||||
char *oldname, *newname;
|
||||
spa_t *spa;
|
||||
|
||||
(void) rw_wrlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_WRITER);
|
||||
|
||||
oldname = ztest_opts.zo_pool;
|
||||
newname = umem_alloc(strlen(oldname) + 5, UMEM_NOFAIL);
|
||||
@ -5319,7 +5320,7 @@ ztest_spa_rename(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
umem_free(newname, strlen(newname) + 1);
|
||||
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5674,18 +5675,18 @@ ztest_dataset_open(int d)
|
||||
|
||||
ztest_dataset_name(name, ztest_opts.zo_pool, d);
|
||||
|
||||
(void) rw_rdlock(&ztest_name_lock);
|
||||
rw_enter(&ztest_name_lock, RW_READER);
|
||||
|
||||
error = ztest_dataset_create(name);
|
||||
if (error == ENOSPC) {
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
ztest_record_enospc(FTAG);
|
||||
return (error);
|
||||
}
|
||||
ASSERT(error == 0 || error == EEXIST);
|
||||
|
||||
VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os));
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
rw_exit(&ztest_name_lock);
|
||||
|
||||
ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os);
|
||||
|
||||
@ -5747,8 +5748,8 @@ ztest_run(ztest_shared_t *zs)
|
||||
/*
|
||||
* Initialize parent/child shared state.
|
||||
*/
|
||||
VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
|
||||
VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
|
||||
mutex_init(&ztest_vdev_lock, NULL, USYNC_THREAD, NULL);
|
||||
rw_init(&ztest_name_lock, NULL, USYNC_THREAD, NULL);
|
||||
|
||||
zs->zs_thread_start = gethrtime();
|
||||
zs->zs_thread_stop =
|
||||
@ -5760,7 +5761,7 @@ ztest_run(ztest_shared_t *zs)
|
||||
ztest_random(ztest_opts.zo_passtime * NANOSEC);
|
||||
}
|
||||
|
||||
(void) _mutex_init(&zcl.zcl_callbacks_lock, USYNC_THREAD, NULL);
|
||||
mutex_init(&zcl.zcl_callbacks_lock, NULL, USYNC_THREAD, NULL);
|
||||
|
||||
list_create(&zcl.zcl_callbacks, sizeof (ztest_cb_data_t),
|
||||
offsetof(ztest_cb_data_t, zcd_node));
|
||||
@ -5907,10 +5908,10 @@ ztest_run(ztest_shared_t *zs)
|
||||
|
||||
list_destroy(&zcl.zcl_callbacks);
|
||||
|
||||
(void) _mutex_destroy(&zcl.zcl_callbacks_lock);
|
||||
mutex_destroy(&zcl.zcl_callbacks_lock);
|
||||
|
||||
(void) rwlock_destroy(&ztest_name_lock);
|
||||
(void) _mutex_destroy(&ztest_vdev_lock);
|
||||
rw_destroy(&ztest_name_lock);
|
||||
mutex_destroy(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6054,8 +6055,8 @@ ztest_init(ztest_shared_t *zs)
|
||||
spa_t *spa;
|
||||
nvlist_t *nvroot, *props;
|
||||
|
||||
VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
|
||||
VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
|
||||
mutex_init(&ztest_vdev_lock, NULL, USYNC_THREAD, NULL);
|
||||
rw_init(&ztest_name_lock, NULL, USYNC_THREAD, NULL);
|
||||
|
||||
kernel_init(FREAD | FWRITE);
|
||||
|
||||
@ -6092,8 +6093,8 @@ ztest_init(ztest_shared_t *zs)
|
||||
|
||||
ztest_run_zdb(ztest_opts.zo_pool);
|
||||
|
||||
(void) rwlock_destroy(&ztest_name_lock);
|
||||
(void) _mutex_destroy(&ztest_vdev_lock);
|
||||
rw_destroy(&ztest_name_lock);
|
||||
mutex_destroy(&ztest_vdev_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -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) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -41,12 +42,14 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
extern void system_taskq_init(void);
|
||||
extern void system_taskq_fini(void);
|
||||
|
||||
/*
|
||||
* Emulation of kernel services in userland.
|
||||
*/
|
||||
|
||||
int aok;
|
||||
uint64_t physmem;
|
||||
pgcnt_t physmem;
|
||||
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
||||
char hw_serial[HW_HOSTID_LEN];
|
||||
kmutex_t cpu_lock;
|
||||
@ -59,336 +62,6 @@ struct utsname utsname = {
|
||||
"userland", "libzpool", "1", "1", "na"
|
||||
};
|
||||
|
||||
/* this only exists to have its address taken */
|
||||
struct proc p0;
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* threads
|
||||
* =========================================================================
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
kthread_t *
|
||||
zk_thread_create(void (*func)(), void *arg)
|
||||
{
|
||||
thread_t tid;
|
||||
|
||||
VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
|
||||
&tid) == 0);
|
||||
|
||||
return ((void *)(uintptr_t)tid);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* kstats
|
||||
* =========================================================================
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
kstat_t *
|
||||
kstat_create(const char *module, int instance, const char *name,
|
||||
const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_named_init(kstat_named_t *knp, const char *name, uchar_t type)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_install(kstat_t *ksp)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_delete(kstat_t *ksp)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_waitq_enter(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_waitq_exit(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_runq_enter(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_runq_exit(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_waitq_to_runq(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
kstat_runq_back_to_waitq(kstat_io_t *kiop)
|
||||
{}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* mutexes
|
||||
* =========================================================================
|
||||
*/
|
||||
void
|
||||
zmutex_init(kmutex_t *mp)
|
||||
{
|
||||
mp->m_owner = NULL;
|
||||
mp->initialized = B_TRUE;
|
||||
(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
zmutex_destroy(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner == NULL);
|
||||
(void) _mutex_destroy(&(mp)->m_lock);
|
||||
mp->m_owner = (void *)-1UL;
|
||||
mp->initialized = B_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
mutex_enter(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner != (void *)-1UL);
|
||||
ASSERT(mp->m_owner != curthread);
|
||||
VERIFY(mutex_lock(&mp->m_lock) == 0);
|
||||
ASSERT(mp->m_owner == NULL);
|
||||
mp->m_owner = curthread;
|
||||
}
|
||||
|
||||
int
|
||||
mutex_tryenter(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mp->m_owner != (void *)-1UL);
|
||||
if (0 == mutex_trylock(&mp->m_lock)) {
|
||||
ASSERT(mp->m_owner == NULL);
|
||||
mp->m_owner = curthread;
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutex_exit(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
ASSERT(mutex_owner(mp) == curthread);
|
||||
mp->m_owner = NULL;
|
||||
VERIFY(mutex_unlock(&mp->m_lock) == 0);
|
||||
}
|
||||
|
||||
void *
|
||||
mutex_owner(kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mp->initialized == B_TRUE);
|
||||
return (mp->m_owner);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* rwlocks
|
||||
* =========================================================================
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
|
||||
{
|
||||
rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
|
||||
rwlp->rw_owner = NULL;
|
||||
rwlp->initialized = B_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
rw_destroy(krwlock_t *rwlp)
|
||||
{
|
||||
rwlock_destroy(&rwlp->rw_lock);
|
||||
rwlp->rw_owner = (void *)-1UL;
|
||||
rwlp->initialized = B_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
rw_enter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
ASSERT(!RW_LOCK_HELD(rwlp));
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
ASSERT(rwlp->rw_owner != curthread);
|
||||
|
||||
if (rw == RW_WRITER)
|
||||
VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
|
||||
else
|
||||
VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
|
||||
|
||||
rwlp->rw_owner = curthread;
|
||||
}
|
||||
|
||||
void
|
||||
rw_exit(krwlock_t *rwlp)
|
||||
{
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
|
||||
rwlp->rw_owner = NULL;
|
||||
VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
rw_tryenter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
|
||||
if (rw == RW_WRITER)
|
||||
rv = rw_trywrlock(&rwlp->rw_lock);
|
||||
else
|
||||
rv = rw_tryrdlock(&rwlp->rw_lock);
|
||||
|
||||
if (rv == 0) {
|
||||
rwlp->rw_owner = curthread;
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
rw_tryupgrade(krwlock_t *rwlp)
|
||||
{
|
||||
ASSERT(rwlp->initialized == B_TRUE);
|
||||
ASSERT(rwlp->rw_owner != (void *)-1UL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* condition variables
|
||||
* =========================================================================
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
cv_init(kcondvar_t *cv, char *name, int type, void *arg)
|
||||
{
|
||||
VERIFY(cond_init(cv, type, NULL) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
cv_destroy(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY(cond_destroy(cv) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
cv_wait(kcondvar_t *cv, kmutex_t *mp)
|
||||
{
|
||||
ASSERT(mutex_owner(mp) == curthread);
|
||||
mp->m_owner = NULL;
|
||||
int ret = cond_wait(cv, &mp->m_lock);
|
||||
VERIFY(ret == 0 || ret == EINTR);
|
||||
mp->m_owner = curthread;
|
||||
}
|
||||
|
||||
clock_t
|
||||
cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
|
||||
{
|
||||
int error;
|
||||
timestruc_t ts;
|
||||
clock_t delta;
|
||||
|
||||
top:
|
||||
delta = abstime - ddi_get_lbolt();
|
||||
if (delta <= 0)
|
||||
return (-1);
|
||||
|
||||
ts.tv_sec = delta / hz;
|
||||
ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
|
||||
|
||||
ASSERT(mutex_owner(mp) == curthread);
|
||||
mp->m_owner = NULL;
|
||||
error = cond_reltimedwait(cv, &mp->m_lock, &ts);
|
||||
mp->m_owner = curthread;
|
||||
|
||||
if (error == ETIME)
|
||||
return (-1);
|
||||
|
||||
if (error == EINTR)
|
||||
goto top;
|
||||
|
||||
ASSERT(error == 0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
clock_t
|
||||
cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
|
||||
int flag)
|
||||
{
|
||||
int error;
|
||||
timestruc_t ts;
|
||||
hrtime_t delta;
|
||||
|
||||
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
|
||||
|
||||
top:
|
||||
delta = tim;
|
||||
if (flag & CALLOUT_FLAG_ABSOLUTE)
|
||||
delta -= gethrtime();
|
||||
|
||||
if (delta <= 0)
|
||||
return (-1);
|
||||
|
||||
ts.tv_sec = delta / NANOSEC;
|
||||
ts.tv_nsec = delta % NANOSEC;
|
||||
|
||||
ASSERT(mutex_owner(mp) == curthread);
|
||||
mp->m_owner = NULL;
|
||||
error = cond_reltimedwait(cv, &mp->m_lock, &ts);
|
||||
mp->m_owner = curthread;
|
||||
|
||||
if (error == ETIME)
|
||||
return (-1);
|
||||
|
||||
if (error == EINTR)
|
||||
goto top;
|
||||
|
||||
ASSERT(error == 0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
cv_signal(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY(cond_signal(cv) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
cv_broadcast(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY(cond_broadcast(cv) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* vnode operations
|
||||
@ -688,56 +361,6 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
|
||||
#endif /* ZFS_DEBUG */
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* cmn_err() and panic()
|
||||
* =========================================================================
|
||||
*/
|
||||
static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
|
||||
static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
|
||||
|
||||
void
|
||||
vpanic(const char *fmt, va_list adx)
|
||||
{
|
||||
char buf[512];
|
||||
(void) vsnprintf(buf, 512, fmt, adx);
|
||||
assfail(buf, NULL, 0);
|
||||
abort(); /* necessary to make vpanic meet noreturn requirements */
|
||||
}
|
||||
|
||||
void
|
||||
panic(const char *fmt, ...)
|
||||
{
|
||||
va_list adx;
|
||||
|
||||
va_start(adx, fmt);
|
||||
vpanic(fmt, adx);
|
||||
va_end(adx);
|
||||
}
|
||||
|
||||
void
|
||||
vcmn_err(int ce, const char *fmt, va_list adx)
|
||||
{
|
||||
if (ce == CE_PANIC)
|
||||
vpanic(fmt, adx);
|
||||
if (ce != CE_NOTE) { /* suppress noise in userland stress testing */
|
||||
(void) fprintf(stderr, "%s", ce_prefix[ce]);
|
||||
(void) vfprintf(stderr, fmt, adx);
|
||||
(void) fprintf(stderr, "%s", ce_suffix[ce]);
|
||||
}
|
||||
}
|
||||
|
||||
/*PRINTFLIKE2*/
|
||||
void
|
||||
cmn_err(int ce, const char *fmt, ...)
|
||||
{
|
||||
va_list adx;
|
||||
|
||||
va_start(adx, fmt);
|
||||
vcmn_err(ce, fmt, adx);
|
||||
va_end(adx);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* kobj interfaces
|
||||
@ -791,124 +414,6 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* misc routines
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
delay(clock_t ticks)
|
||||
{
|
||||
poll(0, 0, ticks * (1000 / hz));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find highest one bit set.
|
||||
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
|
||||
*/
|
||||
int
|
||||
highbit64(uint64_t i)
|
||||
{
|
||||
int h = 1;
|
||||
|
||||
if (i == 0)
|
||||
return (0);
|
||||
if (i & 0xffffffff00000000ULL) {
|
||||
h += 32; i >>= 32;
|
||||
}
|
||||
if (i & 0xffff0000) {
|
||||
h += 16; i >>= 16;
|
||||
}
|
||||
if (i & 0xff00) {
|
||||
h += 8; i >>= 8;
|
||||
}
|
||||
if (i & 0xf0) {
|
||||
h += 4; i >>= 4;
|
||||
}
|
||||
if (i & 0xc) {
|
||||
h += 2; i >>= 2;
|
||||
}
|
||||
if (i & 0x2) {
|
||||
h += 1;
|
||||
}
|
||||
return (h);
|
||||
}
|
||||
|
||||
static int random_fd = -1, urandom_fd = -1;
|
||||
|
||||
static int
|
||||
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
|
||||
{
|
||||
size_t resid = len;
|
||||
ssize_t bytes;
|
||||
|
||||
ASSERT(fd != -1);
|
||||
|
||||
while (resid != 0) {
|
||||
bytes = read(fd, ptr, resid);
|
||||
ASSERT3S(bytes, >=, 0);
|
||||
ptr += bytes;
|
||||
resid -= bytes;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
random_get_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
return (random_get_bytes_common(ptr, len, random_fd));
|
||||
}
|
||||
|
||||
int
|
||||
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
return (random_get_bytes_common(ptr, len, urandom_fd));
|
||||
}
|
||||
|
||||
int
|
||||
ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
|
||||
{
|
||||
char *end;
|
||||
|
||||
*result = strtoul(hw_serial, &end, base);
|
||||
if (*result == 0)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
|
||||
{
|
||||
char *end;
|
||||
|
||||
*result = strtoull(str, &end, base);
|
||||
if (*result == 0)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
cyclic_id_t
|
||||
cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
cyclic_remove(cyclic_id_t id)
|
||||
{
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cyclic_reprogram(cyclic_id_t id, hrtime_t expiration)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* kernel emulation setup & teardown
|
||||
@ -939,9 +444,6 @@ kernel_init(int mode)
|
||||
(void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
|
||||
(mode & FWRITE) ? gethostid() : 0);
|
||||
|
||||
VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
|
||||
VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
|
||||
|
||||
system_taskq_init();
|
||||
|
||||
mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
@ -957,12 +459,6 @@ kernel_fini(void)
|
||||
spa_fini();
|
||||
|
||||
system_taskq_fini();
|
||||
|
||||
close(random_fd);
|
||||
close(urandom_fd);
|
||||
|
||||
random_fd = -1;
|
||||
urandom_fd = -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -990,36 +486,6 @@ z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uid_t
|
||||
crgetuid(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
uid_t
|
||||
crgetruid(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t
|
||||
crgetgid(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
crgetngroups(cred_t *cr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t *
|
||||
crgetgroups(cred_t *cr)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
|
||||
{
|
||||
@ -1038,47 +504,6 @@ zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
|
||||
return (0);
|
||||
}
|
||||
|
||||
ksiddomain_t *
|
||||
ksid_lookupdomain(const char *dom)
|
||||
{
|
||||
ksiddomain_t *kd;
|
||||
|
||||
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
|
||||
kd->kd_name = spa_strdup(dom);
|
||||
return (kd);
|
||||
}
|
||||
|
||||
void
|
||||
ksiddomain_rele(ksiddomain_t *ksid)
|
||||
{
|
||||
spa_strfree(ksid->kd_name);
|
||||
umem_free(ksid, sizeof (ksiddomain_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not change the length of the returned string; it must be freed
|
||||
* with strfree().
|
||||
*/
|
||||
char *
|
||||
kmem_asprintf(const char *fmt, ...)
|
||||
{
|
||||
int size;
|
||||
va_list adx;
|
||||
char *buf;
|
||||
|
||||
va_start(adx, fmt);
|
||||
size = vsnprintf(NULL, 0, fmt, adx) + 1;
|
||||
va_end(adx);
|
||||
|
||||
buf = kmem_alloc(size, KM_SLEEP);
|
||||
|
||||
va_start(adx, fmt);
|
||||
size = vsnprintf(buf, size, fmt, adx);
|
||||
va_end(adx);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
zfs_onexit_fd_hold(int fd, minor_t *minorp)
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_CONTEXT_H
|
||||
@ -32,14 +33,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _SYS_MUTEX_H
|
||||
#define _SYS_RWLOCK_H
|
||||
#define _SYS_CONDVAR_H
|
||||
#define _SYS_SYSTM_H
|
||||
#define _SYS_T_LOCK_H
|
||||
#define _SYNCH_H
|
||||
|
||||
#define _SYS_VNODE_H
|
||||
#define _SYS_VFS_H
|
||||
#define _SYS_SUNDDI_H
|
||||
#define _SYS_CALLB_H
|
||||
|
||||
#include <stdio.h>
|
||||
@ -51,7 +48,6 @@ extern "C" {
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <synch.h>
|
||||
#include <thread.h>
|
||||
#include <assert.h>
|
||||
#include <alloca.h>
|
||||
@ -80,24 +76,27 @@ extern "C" {
|
||||
#include <sys/u8_textprep.h>
|
||||
#include <sys/sysevent/eventdefs.h>
|
||||
#include <sys/sysevent/dev.h>
|
||||
#include <sys/sunddi.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/taskq.h>
|
||||
#include <sys/taskq_impl.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/cmn_err.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/sid.h>
|
||||
#include <sys/acl.h>
|
||||
#include <sys/bitmap.h>
|
||||
#include <sys/systeminfo.h>
|
||||
#include <sys/cpuvar.h>
|
||||
#include <sys/pset.h>
|
||||
#include <sys/kobj.h>
|
||||
#include <sys/fm/util.h>
|
||||
#include "zfs.h"
|
||||
|
||||
/*
|
||||
* Debugging
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note that we are not using the debugging levels.
|
||||
*/
|
||||
|
||||
#define CE_CONT 0 /* continuation */
|
||||
#define CE_NOTE 1 /* notice */
|
||||
#define CE_WARN 2 /* warning */
|
||||
#define CE_PANIC 3 /* panic */
|
||||
#define CE_IGNORE 4 /* print nothing */
|
||||
|
||||
/*
|
||||
* ZFS debugging
|
||||
*/
|
||||
@ -106,15 +105,6 @@ extern "C" {
|
||||
extern void dprintf_setup(int *argc, char **argv);
|
||||
#endif /* ZFS_DEBUG */
|
||||
|
||||
extern void cmn_err(int, const char *, ...);
|
||||
extern void vcmn_err(int, const char *, __va_list);
|
||||
extern void panic(const char *, ...) __NORETURN;
|
||||
extern void vpanic(const char *, __va_list) __NORETURN;
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
extern int aok;
|
||||
|
||||
/*
|
||||
* DTrace SDT probes have different signatures in userland than they do in
|
||||
* the kernel. If they're being used in kernel code, re-define them out of
|
||||
@ -174,232 +164,15 @@ extern int aok;
|
||||
/*
|
||||
* Threads
|
||||
*/
|
||||
#define curthread ((void *)(uintptr_t)thr_self())
|
||||
|
||||
#define kpreempt(x) yield()
|
||||
|
||||
typedef struct kthread kthread_t;
|
||||
|
||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||
zk_thread_create(func, arg)
|
||||
#define thread_exit() thr_exit(NULL)
|
||||
#define thread_join(t) panic("libzpool cannot join threads")
|
||||
|
||||
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
|
||||
|
||||
/* in libzpool, p0 exists only to have its address taken */
|
||||
struct proc {
|
||||
uintptr_t this_is_never_used_dont_dereference_it;
|
||||
};
|
||||
|
||||
extern struct proc p0;
|
||||
#define curproc (&p0)
|
||||
|
||||
#define PS_NONE -1
|
||||
|
||||
extern kthread_t *zk_thread_create(void (*func)(void*), void *arg,
|
||||
uint64_t len);
|
||||
|
||||
#define issig(why) (FALSE)
|
||||
#define ISSIG(thr, why) (FALSE)
|
||||
|
||||
/*
|
||||
* Mutexes
|
||||
*/
|
||||
typedef struct kmutex {
|
||||
void *m_owner;
|
||||
boolean_t initialized;
|
||||
mutex_t m_lock;
|
||||
} kmutex_t;
|
||||
|
||||
#define MUTEX_DEFAULT USYNC_THREAD
|
||||
#undef MUTEX_HELD
|
||||
#undef MUTEX_NOT_HELD
|
||||
#define MUTEX_HELD(m) _mutex_held(&(m)->m_lock)
|
||||
#define MUTEX_NOT_HELD(m) (!MUTEX_HELD(m))
|
||||
|
||||
/*
|
||||
* Argh -- we have to get cheesy here because the kernel and userland
|
||||
* have different signatures for the same routine.
|
||||
*/
|
||||
extern int _mutex_init(mutex_t *mp, int type, void *arg);
|
||||
extern int _mutex_destroy(mutex_t *mp);
|
||||
|
||||
#define mutex_init(mp, b, c, d) zmutex_init((kmutex_t *)(mp))
|
||||
#define mutex_destroy(mp) zmutex_destroy((kmutex_t *)(mp))
|
||||
|
||||
extern void zmutex_init(kmutex_t *mp);
|
||||
extern void zmutex_destroy(kmutex_t *mp);
|
||||
extern void mutex_enter(kmutex_t *mp);
|
||||
extern void mutex_exit(kmutex_t *mp);
|
||||
extern int mutex_tryenter(kmutex_t *mp);
|
||||
extern void *mutex_owner(kmutex_t *mp);
|
||||
|
||||
/*
|
||||
* RW locks
|
||||
*/
|
||||
typedef struct krwlock {
|
||||
void *rw_owner;
|
||||
boolean_t initialized;
|
||||
rwlock_t rw_lock;
|
||||
} krwlock_t;
|
||||
|
||||
typedef int krw_t;
|
||||
|
||||
#define RW_READER 0
|
||||
#define RW_WRITER 1
|
||||
#define RW_DEFAULT USYNC_THREAD
|
||||
|
||||
#undef RW_READ_HELD
|
||||
#define RW_READ_HELD(x) _rw_read_held(&(x)->rw_lock)
|
||||
|
||||
#undef RW_WRITE_HELD
|
||||
#define RW_WRITE_HELD(x) _rw_write_held(&(x)->rw_lock)
|
||||
|
||||
#undef RW_LOCK_HELD
|
||||
#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x))
|
||||
|
||||
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
|
||||
extern void rw_destroy(krwlock_t *rwlp);
|
||||
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryupgrade(krwlock_t *rwlp);
|
||||
extern void rw_exit(krwlock_t *rwlp);
|
||||
#define rw_downgrade(rwlp) do { } while (0)
|
||||
|
||||
extern uid_t crgetuid(cred_t *cr);
|
||||
extern uid_t crgetruid(cred_t *cr);
|
||||
extern gid_t crgetgid(cred_t *cr);
|
||||
extern int crgetngroups(cred_t *cr);
|
||||
extern gid_t *crgetgroups(cred_t *cr);
|
||||
|
||||
/*
|
||||
* Condition variables
|
||||
*/
|
||||
typedef cond_t kcondvar_t;
|
||||
|
||||
#define CV_DEFAULT USYNC_THREAD
|
||||
#define CALLOUT_FLAG_ABSOLUTE 0x2
|
||||
|
||||
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
|
||||
extern void cv_destroy(kcondvar_t *cv);
|
||||
extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
|
||||
extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
|
||||
extern clock_t cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
|
||||
hrtime_t res, int flag);
|
||||
extern void cv_signal(kcondvar_t *cv);
|
||||
extern void cv_broadcast(kcondvar_t *cv);
|
||||
|
||||
/*
|
||||
* Thread-specific data
|
||||
*/
|
||||
#define tsd_get(k) pthread_getspecific(k)
|
||||
#define tsd_set(k, v) pthread_setspecific(k, v)
|
||||
#define tsd_create(kp, d) pthread_key_create(kp, d)
|
||||
#define tsd_destroy(kp) /* nothing */
|
||||
|
||||
/*
|
||||
* kstat creation, installation and deletion
|
||||
*/
|
||||
extern kstat_t *kstat_create(const char *, int,
|
||||
const char *, const char *, uchar_t, ulong_t, uchar_t);
|
||||
extern void kstat_named_init(kstat_named_t *, const char *, uchar_t);
|
||||
extern void kstat_install(kstat_t *);
|
||||
extern void kstat_delete(kstat_t *);
|
||||
extern void kstat_waitq_enter(kstat_io_t *);
|
||||
extern void kstat_waitq_exit(kstat_io_t *);
|
||||
extern void kstat_runq_enter(kstat_io_t *);
|
||||
extern void kstat_runq_exit(kstat_io_t *);
|
||||
extern void kstat_waitq_to_runq(kstat_io_t *);
|
||||
extern void kstat_runq_back_to_waitq(kstat_io_t *);
|
||||
|
||||
/*
|
||||
* Kernel memory
|
||||
*/
|
||||
#define KM_SLEEP UMEM_NOFAIL
|
||||
#define KM_PUSHPAGE KM_SLEEP
|
||||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define KMC_NOTOUCH 0 /* not needed for userland caches */
|
||||
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
|
||||
#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
|
||||
#define kmem_free(_b, _s) umem_free(_b, _s)
|
||||
#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
|
||||
umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
|
||||
#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
|
||||
#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
|
||||
#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
|
||||
#define kmem_debugging() 0
|
||||
#define kmem_cache_reap_now(_c) /* nothing */
|
||||
#define kmem_cache_set_move(_c, _cb) /* nothing */
|
||||
#define vmem_qcache_reap(_v) /* nothing */
|
||||
#define POINTER_INVALIDATE(_pp) /* nothing */
|
||||
#define POINTER_IS_VALID(_p) 0
|
||||
|
||||
extern vmem_t *zio_arena;
|
||||
|
||||
typedef umem_cache_t kmem_cache_t;
|
||||
|
||||
typedef enum kmem_cbrc {
|
||||
KMEM_CBRC_YES,
|
||||
KMEM_CBRC_NO,
|
||||
KMEM_CBRC_LATER,
|
||||
KMEM_CBRC_DONT_NEED,
|
||||
KMEM_CBRC_DONT_KNOW
|
||||
} kmem_cbrc_t;
|
||||
|
||||
/*
|
||||
* Task queues
|
||||
*/
|
||||
typedef struct taskq taskq_t;
|
||||
typedef uintptr_t taskqid_t;
|
||||
typedef void (task_func_t)(void *);
|
||||
|
||||
typedef struct taskq_ent {
|
||||
struct taskq_ent *tqent_next;
|
||||
struct taskq_ent *tqent_prev;
|
||||
task_func_t *tqent_func;
|
||||
void *tqent_arg;
|
||||
uintptr_t tqent_flags;
|
||||
} taskq_ent_t;
|
||||
|
||||
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
|
||||
|
||||
#define TASKQ_PREPOPULATE 0x0001
|
||||
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
||||
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
||||
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
|
||||
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
|
||||
|
||||
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
|
||||
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
|
||||
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
||||
#define TQ_FRONT 0x08 /* Queue in front */
|
||||
|
||||
|
||||
extern taskq_t *system_taskq;
|
||||
|
||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||
#define taskq_create_proc(a, b, c, d, e, p, f) \
|
||||
(taskq_create(a, b, c, d, e, f))
|
||||
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
||||
(taskq_create(a, b, maxclsyspri, d, e, f))
|
||||
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||
taskq_ent_t *);
|
||||
extern void taskq_destroy(taskq_t *);
|
||||
extern void taskq_wait(taskq_t *);
|
||||
extern int taskq_member(taskq_t *, void *);
|
||||
extern void system_taskq_init(void);
|
||||
extern void system_taskq_fini(void);
|
||||
|
||||
#define XVA_MAPSIZE 3
|
||||
#define XVA_MAGIC 0x78766174
|
||||
|
||||
/*
|
||||
* vnodes
|
||||
*/
|
||||
#define XVA_MAPSIZE 3
|
||||
#define XVA_MAGIC 0x78766174
|
||||
|
||||
typedef struct vnode {
|
||||
uint64_t v_size;
|
||||
int v_fd;
|
||||
@ -499,26 +272,13 @@ extern void vn_close(vnode_t *vp);
|
||||
extern vnode_t *rootdir;
|
||||
|
||||
#include <sys/file.h> /* for FREAD, FWRITE, etc */
|
||||
#include <sys/sunddi.h> /* for ddi_strtoul, ddi_strtoull, etc */
|
||||
#include <sys/cyclic.h> /* for cyclic_add, cyclic remove, etc */
|
||||
#include <vm/seg_kmem.h> /* for zio_arena */
|
||||
|
||||
/*
|
||||
* Random stuff
|
||||
*/
|
||||
#define ddi_get_lbolt() (gethrtime() >> 23)
|
||||
#define ddi_get_lbolt64() (gethrtime() >> 23)
|
||||
#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
|
||||
|
||||
extern void delay(clock_t ticks);
|
||||
|
||||
#define SEC_TO_TICK(sec) ((sec) * hz)
|
||||
#define NSEC_TO_TICK(usec) ((usec) / (NANOSEC / hz))
|
||||
|
||||
#define gethrestime_sec() time(NULL)
|
||||
#define gethrestime(t) \
|
||||
do {\
|
||||
(t)->tv_sec = gethrestime_sec();\
|
||||
(t)->tv_nsec = 0;\
|
||||
} while (0);
|
||||
|
||||
#define max_ncpus 64
|
||||
#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
|
||||
|
||||
@ -527,22 +287,10 @@ extern void delay(clock_t ticks);
|
||||
|
||||
#define CPU_SEQID (thr_self() & (max_ncpus - 1))
|
||||
|
||||
#define kcred NULL
|
||||
#define CRED() NULL
|
||||
|
||||
#define ptob(x) ((x) * PAGESIZE)
|
||||
|
||||
extern uint64_t physmem;
|
||||
|
||||
extern int highbit64(uint64_t i);
|
||||
extern int random_get_bytes(uint8_t *ptr, size_t len);
|
||||
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
|
||||
|
||||
extern void kernel_init(int);
|
||||
extern void kernel_fini(void);
|
||||
|
||||
struct spa;
|
||||
extern void nicenum(uint64_t num, char *buf, size_t);
|
||||
extern void show_pool_stats(struct spa *);
|
||||
extern int set_global_var(char *arg);
|
||||
|
||||
@ -570,127 +318,14 @@ typedef struct callb_cpr {
|
||||
#define zone_dataset_visible(x, y) (1)
|
||||
#define INGLOBALZONE(z) (1)
|
||||
|
||||
extern char *kmem_asprintf(const char *fmt, ...);
|
||||
#define strfree(str) kmem_free((str), strlen(str) + 1)
|
||||
|
||||
/*
|
||||
* Hostname information
|
||||
*/
|
||||
extern char hw_serial[]; /* for userland-emulated hostid access */
|
||||
extern int ddi_strtoul(const char *str, char **nptr, int base,
|
||||
unsigned long *result);
|
||||
|
||||
extern int ddi_strtoull(const char *str, char **nptr, int base,
|
||||
u_longlong_t *result);
|
||||
|
||||
/* ZFS Boot Related stuff. */
|
||||
|
||||
struct _buf {
|
||||
intptr_t _fd;
|
||||
};
|
||||
|
||||
struct bootstat {
|
||||
uint64_t st_size;
|
||||
};
|
||||
|
||||
typedef struct ace_object {
|
||||
uid_t a_who;
|
||||
uint32_t a_access_mask;
|
||||
uint16_t a_flags;
|
||||
uint16_t a_type;
|
||||
uint8_t a_obj_type[16];
|
||||
uint8_t a_inherit_obj_type[16];
|
||||
} ace_object_t;
|
||||
|
||||
|
||||
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
|
||||
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
|
||||
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
|
||||
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
|
||||
|
||||
extern struct _buf *kobj_open_file(char *name);
|
||||
extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
|
||||
unsigned off);
|
||||
extern void kobj_close_file(struct _buf *file);
|
||||
extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
|
||||
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
|
||||
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
|
||||
cred_t *cr);
|
||||
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
|
||||
extern zoneid_t getzoneid(void);
|
||||
|
||||
/* SID stuff */
|
||||
typedef struct ksiddomain {
|
||||
uint_t kd_ref;
|
||||
uint_t kd_len;
|
||||
char *kd_name;
|
||||
} ksiddomain_t;
|
||||
|
||||
ksiddomain_t *ksid_lookupdomain(const char *);
|
||||
void ksiddomain_rele(ksiddomain_t *);
|
||||
|
||||
#define DDI_SLEEP KM_SLEEP
|
||||
#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \
|
||||
sysevent_post_event(_c, _d, _b, "libzpool", _e, _f)
|
||||
|
||||
/*
|
||||
* Cyclic information
|
||||
*/
|
||||
extern kmutex_t cpu_lock;
|
||||
|
||||
typedef uintptr_t cyclic_id_t;
|
||||
typedef uint16_t cyc_level_t;
|
||||
typedef void (*cyc_func_t)(void *);
|
||||
|
||||
#define CY_LOW_LEVEL 0
|
||||
#define CY_INFINITY INT64_MAX
|
||||
#define CYCLIC_NONE ((cyclic_id_t)0)
|
||||
|
||||
typedef struct cyc_time {
|
||||
hrtime_t cyt_when;
|
||||
hrtime_t cyt_interval;
|
||||
} cyc_time_t;
|
||||
|
||||
typedef struct cyc_handler {
|
||||
cyc_func_t cyh_func;
|
||||
void *cyh_arg;
|
||||
cyc_level_t cyh_level;
|
||||
} cyc_handler_t;
|
||||
|
||||
extern cyclic_id_t cyclic_add(cyc_handler_t *, cyc_time_t *);
|
||||
extern void cyclic_remove(cyclic_id_t);
|
||||
extern int cyclic_reprogram(cyclic_id_t, hrtime_t);
|
||||
|
||||
/*
|
||||
* Buf structure
|
||||
*/
|
||||
#define B_BUSY 0x0001
|
||||
#define B_DONE 0x0002
|
||||
#define B_ERROR 0x0004
|
||||
#define B_READ 0x0040 /* read when I/O occurs */
|
||||
#define B_WRITE 0x0100 /* non-read pseudo-flag */
|
||||
|
||||
typedef struct buf {
|
||||
int b_flags;
|
||||
size_t b_bcount;
|
||||
union {
|
||||
caddr_t b_addr;
|
||||
} b_un;
|
||||
|
||||
lldaddr_t _b_blkno;
|
||||
#define b_lblkno _b_blkno._f
|
||||
size_t b_resid;
|
||||
size_t b_bufsize;
|
||||
int (*b_iodone)(struct buf *);
|
||||
int b_error;
|
||||
void *b_private;
|
||||
} buf_t;
|
||||
|
||||
extern void bioinit(buf_t *);
|
||||
extern void biodone(buf_t *);
|
||||
extern void bioerror(buf_t *, int);
|
||||
extern int geterror(buf_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,342 +0,0 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
int taskq_now;
|
||||
taskq_t *system_taskq;
|
||||
|
||||
#define TASKQ_ACTIVE 0x00010000
|
||||
#define TASKQ_NAMELEN 31
|
||||
|
||||
struct taskq {
|
||||
char tq_name[TASKQ_NAMELEN + 1];
|
||||
kmutex_t tq_lock;
|
||||
krwlock_t tq_threadlock;
|
||||
kcondvar_t tq_dispatch_cv;
|
||||
kcondvar_t tq_wait_cv;
|
||||
thread_t *tq_threadlist;
|
||||
int tq_flags;
|
||||
int tq_active;
|
||||
int tq_nthreads;
|
||||
int tq_nalloc;
|
||||
int tq_minalloc;
|
||||
int tq_maxalloc;
|
||||
kcondvar_t tq_maxalloc_cv;
|
||||
int tq_maxalloc_wait;
|
||||
taskq_ent_t *tq_freelist;
|
||||
taskq_ent_t tq_task;
|
||||
};
|
||||
|
||||
static taskq_ent_t *
|
||||
task_alloc(taskq_t *tq, int tqflags)
|
||||
{
|
||||
taskq_ent_t *t;
|
||||
int rv;
|
||||
|
||||
again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
||||
tq->tq_freelist = t->tqent_next;
|
||||
} else {
|
||||
if (tq->tq_nalloc >= tq->tq_maxalloc) {
|
||||
if (!(tqflags & KM_SLEEP))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* We don't want to exceed tq_maxalloc, but we can't
|
||||
* wait for other tasks to complete (and thus free up
|
||||
* task structures) without risking deadlock with
|
||||
* the caller. So, we just delay for one second
|
||||
* to throttle the allocation rate. If we have tasks
|
||||
* complete before one second timeout expires then
|
||||
* taskq_ent_free will signal us and we will
|
||||
* immediately retry the allocation.
|
||||
*/
|
||||
tq->tq_maxalloc_wait++;
|
||||
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||
&tq->tq_lock, ddi_get_lbolt() + hz);
|
||||
tq->tq_maxalloc_wait--;
|
||||
if (rv > 0)
|
||||
goto again; /* signaled */
|
||||
}
|
||||
mutex_exit(&tq->tq_lock);
|
||||
|
||||
t = kmem_alloc(sizeof (taskq_ent_t), tqflags);
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
if (t != NULL)
|
||||
tq->tq_nalloc++;
|
||||
}
|
||||
return (t);
|
||||
}
|
||||
|
||||
static void
|
||||
task_free(taskq_t *tq, taskq_ent_t *t)
|
||||
{
|
||||
if (tq->tq_nalloc <= tq->tq_minalloc) {
|
||||
t->tqent_next = tq->tq_freelist;
|
||||
tq->tq_freelist = t;
|
||||
} else {
|
||||
tq->tq_nalloc--;
|
||||
mutex_exit(&tq->tq_lock);
|
||||
kmem_free(t, sizeof (taskq_ent_t));
|
||||
mutex_enter(&tq->tq_lock);
|
||||
}
|
||||
|
||||
if (tq->tq_maxalloc_wait)
|
||||
cv_signal(&tq->tq_maxalloc_cv);
|
||||
}
|
||||
|
||||
taskqid_t
|
||||
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
|
||||
{
|
||||
taskq_ent_t *t;
|
||||
|
||||
if (taskq_now) {
|
||||
func(arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
ASSERT(tq->tq_flags & TASKQ_ACTIVE);
|
||||
if ((t = task_alloc(tq, tqflags)) == NULL) {
|
||||
mutex_exit(&tq->tq_lock);
|
||||
return (0);
|
||||
}
|
||||
if (tqflags & TQ_FRONT) {
|
||||
t->tqent_next = tq->tq_task.tqent_next;
|
||||
t->tqent_prev = &tq->tq_task;
|
||||
} else {
|
||||
t->tqent_next = &tq->tq_task;
|
||||
t->tqent_prev = tq->tq_task.tqent_prev;
|
||||
}
|
||||
t->tqent_next->tqent_prev = t;
|
||||
t->tqent_prev->tqent_next = t;
|
||||
t->tqent_func = func;
|
||||
t->tqent_arg = arg;
|
||||
t->tqent_flags = 0;
|
||||
cv_signal(&tq->tq_dispatch_cv);
|
||||
mutex_exit(&tq->tq_lock);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||
taskq_ent_t *t)
|
||||
{
|
||||
ASSERT(func != NULL);
|
||||
ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
|
||||
|
||||
/*
|
||||
* Mark it as a prealloc'd task. This is important
|
||||
* to ensure that we don't free it later.
|
||||
*/
|
||||
t->tqent_flags |= TQENT_FLAG_PREALLOC;
|
||||
/*
|
||||
* Enqueue the task to the underlying queue.
|
||||
*/
|
||||
mutex_enter(&tq->tq_lock);
|
||||
|
||||
if (flags & TQ_FRONT) {
|
||||
t->tqent_next = tq->tq_task.tqent_next;
|
||||
t->tqent_prev = &tq->tq_task;
|
||||
} else {
|
||||
t->tqent_next = &tq->tq_task;
|
||||
t->tqent_prev = tq->tq_task.tqent_prev;
|
||||
}
|
||||
t->tqent_next->tqent_prev = t;
|
||||
t->tqent_prev->tqent_next = t;
|
||||
t->tqent_func = func;
|
||||
t->tqent_arg = arg;
|
||||
cv_signal(&tq->tq_dispatch_cv);
|
||||
mutex_exit(&tq->tq_lock);
|
||||
}
|
||||
|
||||
void
|
||||
taskq_wait(taskq_t *tq)
|
||||
{
|
||||
mutex_enter(&tq->tq_lock);
|
||||
while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
|
||||
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
|
||||
mutex_exit(&tq->tq_lock);
|
||||
}
|
||||
|
||||
static void *
|
||||
taskq_thread(void *arg)
|
||||
{
|
||||
taskq_t *tq = arg;
|
||||
taskq_ent_t *t;
|
||||
boolean_t prealloc;
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
while (tq->tq_flags & TASKQ_ACTIVE) {
|
||||
if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
|
||||
if (--tq->tq_active == 0)
|
||||
cv_broadcast(&tq->tq_wait_cv);
|
||||
cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
|
||||
tq->tq_active++;
|
||||
continue;
|
||||
}
|
||||
t->tqent_prev->tqent_next = t->tqent_next;
|
||||
t->tqent_next->tqent_prev = t->tqent_prev;
|
||||
t->tqent_next = NULL;
|
||||
t->tqent_prev = NULL;
|
||||
prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC;
|
||||
mutex_exit(&tq->tq_lock);
|
||||
|
||||
rw_enter(&tq->tq_threadlock, RW_READER);
|
||||
t->tqent_func(t->tqent_arg);
|
||||
rw_exit(&tq->tq_threadlock);
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
if (!prealloc)
|
||||
task_free(tq, t);
|
||||
}
|
||||
tq->tq_nthreads--;
|
||||
cv_broadcast(&tq->tq_wait_cv);
|
||||
mutex_exit(&tq->tq_lock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
taskq_t *
|
||||
taskq_create(const char *name, int nthreads, pri_t pri,
|
||||
int minalloc, int maxalloc, uint_t flags)
|
||||
{
|
||||
taskq_t *tq = kmem_zalloc(sizeof (taskq_t), KM_SLEEP);
|
||||
int t;
|
||||
|
||||
if (flags & TASKQ_THREADS_CPU_PCT) {
|
||||
int pct;
|
||||
ASSERT3S(nthreads, >=, 0);
|
||||
ASSERT3S(nthreads, <=, 100);
|
||||
pct = MIN(nthreads, 100);
|
||||
pct = MAX(pct, 0);
|
||||
|
||||
nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100;
|
||||
nthreads = MAX(nthreads, 1); /* need at least 1 thread */
|
||||
} else {
|
||||
ASSERT3S(nthreads, >=, 1);
|
||||
}
|
||||
|
||||
rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
|
||||
mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL);
|
||||
(void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1);
|
||||
tq->tq_flags = flags | TASKQ_ACTIVE;
|
||||
tq->tq_active = nthreads;
|
||||
tq->tq_nthreads = nthreads;
|
||||
tq->tq_minalloc = minalloc;
|
||||
tq->tq_maxalloc = maxalloc;
|
||||
tq->tq_task.tqent_next = &tq->tq_task;
|
||||
tq->tq_task.tqent_prev = &tq->tq_task;
|
||||
tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP);
|
||||
|
||||
if (flags & TASKQ_PREPOPULATE) {
|
||||
mutex_enter(&tq->tq_lock);
|
||||
while (minalloc-- > 0)
|
||||
task_free(tq, task_alloc(tq, KM_SLEEP));
|
||||
mutex_exit(&tq->tq_lock);
|
||||
}
|
||||
|
||||
for (t = 0; t < nthreads; t++)
|
||||
(void) thr_create(0, 0, taskq_thread,
|
||||
tq, THR_BOUND, &tq->tq_threadlist[t]);
|
||||
|
||||
return (tq);
|
||||
}
|
||||
|
||||
void
|
||||
taskq_destroy(taskq_t *tq)
|
||||
{
|
||||
int t;
|
||||
int nthreads = tq->tq_nthreads;
|
||||
|
||||
taskq_wait(tq);
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
|
||||
tq->tq_flags &= ~TASKQ_ACTIVE;
|
||||
cv_broadcast(&tq->tq_dispatch_cv);
|
||||
|
||||
while (tq->tq_nthreads != 0)
|
||||
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
|
||||
|
||||
tq->tq_minalloc = 0;
|
||||
while (tq->tq_nalloc != 0) {
|
||||
ASSERT(tq->tq_freelist != NULL);
|
||||
task_free(tq, task_alloc(tq, KM_SLEEP));
|
||||
}
|
||||
|
||||
mutex_exit(&tq->tq_lock);
|
||||
|
||||
for (t = 0; t < nthreads; t++)
|
||||
(void) thr_join(tq->tq_threadlist[t], NULL, NULL);
|
||||
|
||||
kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
|
||||
|
||||
rw_destroy(&tq->tq_threadlock);
|
||||
mutex_destroy(&tq->tq_lock);
|
||||
cv_destroy(&tq->tq_dispatch_cv);
|
||||
cv_destroy(&tq->tq_wait_cv);
|
||||
cv_destroy(&tq->tq_maxalloc_cv);
|
||||
|
||||
kmem_free(tq, sizeof (taskq_t));
|
||||
}
|
||||
|
||||
int
|
||||
taskq_member(taskq_t *tq, void *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (taskq_now)
|
||||
return (1);
|
||||
|
||||
for (i = 0; i < tq->tq_nthreads; i++)
|
||||
if (tq->tq_threadlist[i] == (thread_t)(uintptr_t)t)
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
system_taskq_init(void)
|
||||
{
|
||||
system_taskq = taskq_create("system_taskq", 64, minclsyspri, 4, 512,
|
||||
TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
|
||||
}
|
||||
|
||||
void
|
||||
system_taskq_fini(void)
|
||||
{
|
||||
taskq_destroy(system_taskq);
|
||||
system_taskq = NULL; /* defensive */
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 by Delphix. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -34,6 +35,8 @@
|
||||
#include <sys/refcount.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
extern void nicenum(uint64_t num, char *buf, size_t);
|
||||
|
||||
/*
|
||||
* Routines needed by more than one client of libzpool.
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
@ -59,7 +60,9 @@ static dnode_phys_t dnode_phys_zero;
|
||||
int zfs_default_bs = SPA_MINBLOCKSHIFT;
|
||||
int zfs_default_ibs = DN_MAX_INDBLKSHIFT;
|
||||
|
||||
#ifdef _KERNEL
|
||||
static kmem_cbrc_t dnode_move(void *, void *, size_t, void *);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
static int
|
||||
dbuf_compare(const void *x1, const void *x2)
|
||||
@ -213,7 +216,9 @@ dnode_init(void)
|
||||
dnode_cache = kmem_cache_create("dnode_t",
|
||||
sizeof (dnode_t),
|
||||
0, dnode_cons, dnode_dest, NULL, NULL, NULL, 0);
|
||||
#ifdef _KERNEL
|
||||
kmem_cache_set_move(dnode_cache, dnode_move);
|
||||
#endif /* _KERNEL */
|
||||
}
|
||||
|
||||
void
|
||||
@ -405,7 +410,9 @@ dnode_create(objset_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db,
|
||||
dnode_t *dn;
|
||||
|
||||
dn = kmem_cache_alloc(dnode_cache, KM_SLEEP);
|
||||
#ifdef _KERNEL
|
||||
ASSERT(!POINTER_IS_VALID(dn->dn_objset));
|
||||
#endif /* _KERNEL */
|
||||
dn->dn_moved = 0;
|
||||
|
||||
/*
|
||||
@ -697,6 +704,7 @@ static struct {
|
||||
} dnode_move_stats;
|
||||
#endif /* DNODE_STATS */
|
||||
|
||||
#ifdef _KERNEL
|
||||
static void
|
||||
dnode_move_impl(dnode_t *odn, dnode_t *ndn)
|
||||
{
|
||||
@ -833,7 +841,6 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
|
||||
odn->dn_moved = (uint8_t)-1;
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*ARGSUSED*/
|
||||
static kmem_cbrc_t
|
||||
dnode_move(void *buf, void *newbuf, size_t size, void *arg)
|
||||
|
@ -25,6 +25,7 @@
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ACL_H
|
||||
@ -138,7 +139,7 @@ typedef struct acl_info acl_t;
|
||||
#define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED| \
|
||||
ACL_DEFAULTED)
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if defined(_KERNEL) || defined(_FAKE_KERNEL)
|
||||
|
||||
/*
|
||||
* These are only applicable in a CIFS context.
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
@ -134,7 +135,7 @@ extern "C" {
|
||||
#define BIT_ONLYONESET(u) \
|
||||
((((u) == 0) ? 0 : ((u) & ((u) - 1)) == 0))
|
||||
|
||||
#if defined(_KERNEL) && !defined(_ASM)
|
||||
#if (defined(_KERNEL) || defined(_FAKE_KERNEL)) && !defined(_ASM)
|
||||
#include <sys/atomic.h>
|
||||
|
||||
/*
|
||||
@ -188,7 +189,7 @@ extern int odd_parity(ulong_t);
|
||||
*/
|
||||
#define BITX(u, h, l) (((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
|
||||
|
||||
#endif /* _KERNEL && !_ASM */
|
||||
#endif /* (_KERNEL || _FAKE_KERNEL) && !_ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CPUPART_H
|
||||
@ -40,7 +41,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if defined(_KERNEL) || defined(_FAKE_KERNEL)
|
||||
|
||||
typedef int cpupartid_t;
|
||||
|
||||
@ -148,7 +149,7 @@ extern uint_t cpupart_list(psetid_t *, uint_t, int);
|
||||
extern int cpupart_setattr(psetid_t, uint_t);
|
||||
extern int cpupart_getattr(psetid_t, uint_t *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _KERNEL || _FAKE_KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
* Copyright 2014 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CPUVAR_H
|
||||
@ -32,6 +33,7 @@
|
||||
#include <sys/sysinfo.h> /* has cpu_stat_t definition */
|
||||
#include <sys/disp.h>
|
||||
#include <sys/processor.h>
|
||||
#include <sys/kcpc.h> /* has kcpc_ctx_t definition */
|
||||
|
||||
#include <sys/loadavg.h>
|
||||
#if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
|
||||
@ -614,9 +616,9 @@ extern struct cpu *curcpup(void);
|
||||
#endif /* _KERNEL || _KMEMUSER */
|
||||
|
||||
/*
|
||||
* CPU support routines.
|
||||
* CPU support routines (not for genassym.c)
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(__STDC__) /* not for genassym.c */
|
||||
#if (defined(_KERNEL) || defined(_FAKE_KERNEL)) && defined(__STDC__)
|
||||
|
||||
struct zone;
|
||||
|
||||
@ -823,7 +825,7 @@ extern void populate_idstr(struct cpu *);
|
||||
extern void cpu_vm_data_init(struct cpu *);
|
||||
extern void cpu_vm_data_destroy(struct cpu *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _KERNEL || _FAKE_KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_FM_UTIL_H
|
||||
@ -70,7 +71,7 @@ typedef struct erpt_dump {
|
||||
} ed_tod_base;
|
||||
} erpt_dump_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if defined(_KERNEL) || defined(_FAKE_KERNEL)
|
||||
#include <sys/systm.h>
|
||||
|
||||
#define FM_STK_DEPTH 20 /* maximum stack depth */
|
||||
@ -94,7 +95,7 @@ extern void fm_ereport_post(nvlist_t *, int);
|
||||
extern void fm_payload_stack_add(nvlist_t *, const pc_t *, int);
|
||||
|
||||
extern int is_fm_panic();
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _KERNEL || _FAKE_KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, Joyent, Inc.
|
||||
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
|
||||
@ -340,6 +341,7 @@ typedef struct vnode {
|
||||
|
||||
#define IS_SWAPVP(vp) (((vp)->v_flag & (VISSWAP | VSWAPLIKE)) != 0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
typedef struct vn_vfslocks_entry {
|
||||
rwstlock_t ve_lock;
|
||||
void *ve_vpvfs;
|
||||
@ -348,6 +350,7 @@ typedef struct vn_vfslocks_entry {
|
||||
char pad[64 - sizeof (rwstlock_t) - 2 * sizeof (void *) - \
|
||||
sizeof (uint32_t)];
|
||||
} vn_vfslocks_entry_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following two flags are used to lock the v_vfsmountedhere field
|
||||
|
Loading…
x
Reference in New Issue
Block a user