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:
Alexander Motin 2018-02-21 21:04:46 +00:00
parent ed2ac05a27
commit 81ef5e369c
13 changed files with 181 additions and 1440 deletions

View File

@ -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";

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 */
}

View File

@ -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.
*/

View File

@ -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)

View File

@ -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.

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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