1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy /* 22eda14cbcSMatt Macy * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23eda14cbcSMatt Macy * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 24eda14cbcSMatt Macy * Copyright (c) 2016 Actifio, Inc. All rights reserved. 25eda14cbcSMatt Macy */ 26eda14cbcSMatt Macy 27eda14cbcSMatt Macy #include <assert.h> 28eda14cbcSMatt Macy #include <fcntl.h> 29eda14cbcSMatt Macy #include <libgen.h> 30eda14cbcSMatt Macy #include <poll.h> 31eda14cbcSMatt Macy #include <stdio.h> 32eda14cbcSMatt Macy #include <stdlib.h> 33eda14cbcSMatt Macy #include <string.h> 343ff01b23SMartin Matuska #include <libzutil.h> 35eda14cbcSMatt Macy #include <sys/crypto/icp.h> 36eda14cbcSMatt Macy #include <sys/processor.h> 37eda14cbcSMatt Macy #include <sys/rrwlock.h> 38eda14cbcSMatt Macy #include <sys/spa.h> 39eda14cbcSMatt Macy #include <sys/stat.h> 40eda14cbcSMatt Macy #include <sys/systeminfo.h> 41eda14cbcSMatt Macy #include <sys/time.h> 42eda14cbcSMatt Macy #include <sys/utsname.h> 43eda14cbcSMatt Macy #include <sys/zfs_context.h> 44eda14cbcSMatt Macy #include <sys/zfs_onexit.h> 45eac7052fSMatt Macy #include <sys/zfs_vfsops.h> 46eda14cbcSMatt Macy #include <sys/zstd/zstd.h> 47eda14cbcSMatt Macy #include <sys/zvol.h> 48eda14cbcSMatt Macy #include <zfs_fletcher.h> 49eda14cbcSMatt Macy #include <zlib.h> 50eda14cbcSMatt Macy 51eda14cbcSMatt Macy /* 52eda14cbcSMatt Macy * Emulation of kernel services in userland. 53eda14cbcSMatt Macy */ 54eda14cbcSMatt Macy 55eda14cbcSMatt Macy uint64_t physmem; 56716fd348SMartin Matuska uint32_t hostid; 57eda14cbcSMatt Macy struct utsname hw_utsname; 58eda14cbcSMatt Macy 59eda14cbcSMatt Macy /* If set, all blocks read will be copied to the specified directory. */ 60eda14cbcSMatt Macy char *vn_dumpdir = NULL; 61eda14cbcSMatt Macy 62eda14cbcSMatt Macy /* this only exists to have its address taken */ 63eda14cbcSMatt Macy struct proc p0; 64eda14cbcSMatt Macy 65eda14cbcSMatt Macy /* 66eda14cbcSMatt Macy * ========================================================================= 67eda14cbcSMatt Macy * threads 68eda14cbcSMatt Macy * ========================================================================= 69eda14cbcSMatt Macy * 70eda14cbcSMatt Macy * TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While 71eda14cbcSMatt Macy * TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for 72eda14cbcSMatt Macy * the expected stack depth while small enough to avoid exhausting address 73eda14cbcSMatt Macy * space with high thread counts. 74eda14cbcSMatt Macy */ 75eda14cbcSMatt Macy #define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768) 76eda14cbcSMatt Macy #define TS_STACK_MAX (256 * 1024) 77eda14cbcSMatt Macy 78c03c5b1cSMartin Matuska struct zk_thread_wrapper { 79c03c5b1cSMartin Matuska void (*func)(void *); 80c03c5b1cSMartin Matuska void *arg; 81c03c5b1cSMartin Matuska }; 82c03c5b1cSMartin Matuska 83c03c5b1cSMartin Matuska static void * 84c03c5b1cSMartin Matuska zk_thread_wrapper(void *arg) 85c03c5b1cSMartin Matuska { 86c03c5b1cSMartin Matuska struct zk_thread_wrapper ztw; 87c03c5b1cSMartin Matuska memcpy(&ztw, arg, sizeof (ztw)); 88c03c5b1cSMartin Matuska free(arg); 89c03c5b1cSMartin Matuska ztw.func(ztw.arg); 90c03c5b1cSMartin Matuska return (NULL); 91c03c5b1cSMartin Matuska } 92c03c5b1cSMartin Matuska 93eda14cbcSMatt Macy kthread_t * 94eda14cbcSMatt Macy zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state) 95eda14cbcSMatt Macy { 96eda14cbcSMatt Macy pthread_attr_t attr; 97eda14cbcSMatt Macy pthread_t tid; 98eda14cbcSMatt Macy char *stkstr; 99c03c5b1cSMartin Matuska struct zk_thread_wrapper *ztw; 100eda14cbcSMatt Macy int detachstate = PTHREAD_CREATE_DETACHED; 101eda14cbcSMatt Macy 102eda14cbcSMatt Macy VERIFY0(pthread_attr_init(&attr)); 103eda14cbcSMatt Macy 104eda14cbcSMatt Macy if (state & TS_JOINABLE) 105eda14cbcSMatt Macy detachstate = PTHREAD_CREATE_JOINABLE; 106eda14cbcSMatt Macy 107eda14cbcSMatt Macy VERIFY0(pthread_attr_setdetachstate(&attr, detachstate)); 108eda14cbcSMatt Macy 109eda14cbcSMatt Macy /* 110eda14cbcSMatt Macy * We allow the default stack size in user space to be specified by 111eda14cbcSMatt Macy * setting the ZFS_STACK_SIZE environment variable. This allows us 112eda14cbcSMatt Macy * the convenience of observing and debugging stack overruns in 113eda14cbcSMatt Macy * user space. Explicitly specified stack sizes will be honored. 114eda14cbcSMatt Macy * The usage of ZFS_STACK_SIZE is discussed further in the 115eda14cbcSMatt Macy * ENVIRONMENT VARIABLES sections of the ztest(1) man page. 116eda14cbcSMatt Macy */ 117eda14cbcSMatt Macy if (stksize == 0) { 118eda14cbcSMatt Macy stkstr = getenv("ZFS_STACK_SIZE"); 119eda14cbcSMatt Macy 120eda14cbcSMatt Macy if (stkstr == NULL) 121eda14cbcSMatt Macy stksize = TS_STACK_MAX; 122eda14cbcSMatt Macy else 123eda14cbcSMatt Macy stksize = MAX(atoi(stkstr), TS_STACK_MIN); 124eda14cbcSMatt Macy } 125eda14cbcSMatt Macy 126eda14cbcSMatt Macy VERIFY3S(stksize, >, 0); 127eda14cbcSMatt Macy stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE); 128eda14cbcSMatt Macy 129eda14cbcSMatt Macy /* 130eda14cbcSMatt Macy * If this ever fails, it may be because the stack size is not a 131eda14cbcSMatt Macy * multiple of system page size. 132eda14cbcSMatt Macy */ 133eda14cbcSMatt Macy VERIFY0(pthread_attr_setstacksize(&attr, stksize)); 134eda14cbcSMatt Macy VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE)); 135eda14cbcSMatt Macy 136c03c5b1cSMartin Matuska VERIFY(ztw = malloc(sizeof (*ztw))); 137c03c5b1cSMartin Matuska ztw->func = func; 138c03c5b1cSMartin Matuska ztw->arg = arg; 139c03c5b1cSMartin Matuska VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw)); 140eda14cbcSMatt Macy VERIFY0(pthread_attr_destroy(&attr)); 141eda14cbcSMatt Macy 142eda14cbcSMatt Macy return ((void *)(uintptr_t)tid); 143eda14cbcSMatt Macy } 144eda14cbcSMatt Macy 145eda14cbcSMatt Macy /* 146eda14cbcSMatt Macy * ========================================================================= 147eda14cbcSMatt Macy * kstats 148eda14cbcSMatt Macy * ========================================================================= 149eda14cbcSMatt Macy */ 150eda14cbcSMatt Macy kstat_t * 151eda14cbcSMatt Macy kstat_create(const char *module, int instance, const char *name, 152eda14cbcSMatt Macy const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag) 153eda14cbcSMatt Macy { 154e92ffd9bSMartin Matuska (void) module, (void) instance, (void) name, (void) class, (void) type, 155e92ffd9bSMartin Matuska (void) ndata, (void) ks_flag; 156eda14cbcSMatt Macy return (NULL); 157eda14cbcSMatt Macy } 158eda14cbcSMatt Macy 159eda14cbcSMatt Macy void 160eda14cbcSMatt Macy kstat_install(kstat_t *ksp) 161e92ffd9bSMartin Matuska { 162e92ffd9bSMartin Matuska (void) ksp; 163e92ffd9bSMartin Matuska } 164eda14cbcSMatt Macy 165eda14cbcSMatt Macy void 166eda14cbcSMatt Macy kstat_delete(kstat_t *ksp) 167e92ffd9bSMartin Matuska { 168e92ffd9bSMartin Matuska (void) ksp; 169e92ffd9bSMartin Matuska } 170eda14cbcSMatt Macy 171eda14cbcSMatt Macy void 172eda14cbcSMatt Macy kstat_set_raw_ops(kstat_t *ksp, 173eda14cbcSMatt Macy int (*headers)(char *buf, size_t size), 174eda14cbcSMatt Macy int (*data)(char *buf, size_t size, void *data), 175eda14cbcSMatt Macy void *(*addr)(kstat_t *ksp, loff_t index)) 176e92ffd9bSMartin Matuska { 177e92ffd9bSMartin Matuska (void) ksp, (void) headers, (void) data, (void) addr; 178e92ffd9bSMartin Matuska } 179eda14cbcSMatt Macy 180eda14cbcSMatt Macy /* 181eda14cbcSMatt Macy * ========================================================================= 182eda14cbcSMatt Macy * mutexes 183eda14cbcSMatt Macy * ========================================================================= 184eda14cbcSMatt Macy */ 185eda14cbcSMatt Macy 186eda14cbcSMatt Macy void 187eda14cbcSMatt Macy mutex_init(kmutex_t *mp, char *name, int type, void *cookie) 188eda14cbcSMatt Macy { 189e92ffd9bSMartin Matuska (void) name, (void) type, (void) cookie; 190eda14cbcSMatt Macy VERIFY0(pthread_mutex_init(&mp->m_lock, NULL)); 191eda14cbcSMatt Macy memset(&mp->m_owner, 0, sizeof (pthread_t)); 192eda14cbcSMatt Macy } 193eda14cbcSMatt Macy 194eda14cbcSMatt Macy void 195eda14cbcSMatt Macy mutex_destroy(kmutex_t *mp) 196eda14cbcSMatt Macy { 197eda14cbcSMatt Macy VERIFY0(pthread_mutex_destroy(&mp->m_lock)); 198eda14cbcSMatt Macy } 199eda14cbcSMatt Macy 200eda14cbcSMatt Macy void 201eda14cbcSMatt Macy mutex_enter(kmutex_t *mp) 202eda14cbcSMatt Macy { 203eda14cbcSMatt Macy VERIFY0(pthread_mutex_lock(&mp->m_lock)); 204eda14cbcSMatt Macy mp->m_owner = pthread_self(); 205eda14cbcSMatt Macy } 206eda14cbcSMatt Macy 207eda14cbcSMatt Macy int 208eda14cbcSMatt Macy mutex_tryenter(kmutex_t *mp) 209eda14cbcSMatt Macy { 210e92ffd9bSMartin Matuska int error = pthread_mutex_trylock(&mp->m_lock); 211eda14cbcSMatt Macy if (error == 0) { 212eda14cbcSMatt Macy mp->m_owner = pthread_self(); 213eda14cbcSMatt Macy return (1); 214eda14cbcSMatt Macy } else { 215eda14cbcSMatt Macy VERIFY3S(error, ==, EBUSY); 216eda14cbcSMatt Macy return (0); 217eda14cbcSMatt Macy } 218eda14cbcSMatt Macy } 219eda14cbcSMatt Macy 220eda14cbcSMatt Macy void 221eda14cbcSMatt Macy mutex_exit(kmutex_t *mp) 222eda14cbcSMatt Macy { 223eda14cbcSMatt Macy memset(&mp->m_owner, 0, sizeof (pthread_t)); 224eda14cbcSMatt Macy VERIFY0(pthread_mutex_unlock(&mp->m_lock)); 225eda14cbcSMatt Macy } 226eda14cbcSMatt Macy 227eda14cbcSMatt Macy /* 228eda14cbcSMatt Macy * ========================================================================= 229eda14cbcSMatt Macy * rwlocks 230eda14cbcSMatt Macy * ========================================================================= 231eda14cbcSMatt Macy */ 232eda14cbcSMatt Macy 233eda14cbcSMatt Macy void 234eda14cbcSMatt Macy rw_init(krwlock_t *rwlp, char *name, int type, void *arg) 235eda14cbcSMatt Macy { 236e92ffd9bSMartin Matuska (void) name, (void) type, (void) arg; 237eda14cbcSMatt Macy VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL)); 238eda14cbcSMatt Macy rwlp->rw_readers = 0; 239eda14cbcSMatt Macy rwlp->rw_owner = 0; 240eda14cbcSMatt Macy } 241eda14cbcSMatt Macy 242eda14cbcSMatt Macy void 243eda14cbcSMatt Macy rw_destroy(krwlock_t *rwlp) 244eda14cbcSMatt Macy { 245eda14cbcSMatt Macy VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock)); 246eda14cbcSMatt Macy } 247eda14cbcSMatt Macy 248eda14cbcSMatt Macy void 249eda14cbcSMatt Macy rw_enter(krwlock_t *rwlp, krw_t rw) 250eda14cbcSMatt Macy { 251eda14cbcSMatt Macy if (rw == RW_READER) { 252eda14cbcSMatt Macy VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock)); 253eda14cbcSMatt Macy atomic_inc_uint(&rwlp->rw_readers); 254eda14cbcSMatt Macy } else { 255eda14cbcSMatt Macy VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock)); 256eda14cbcSMatt Macy rwlp->rw_owner = pthread_self(); 257eda14cbcSMatt Macy } 258eda14cbcSMatt Macy } 259eda14cbcSMatt Macy 260eda14cbcSMatt Macy void 261eda14cbcSMatt Macy rw_exit(krwlock_t *rwlp) 262eda14cbcSMatt Macy { 263eda14cbcSMatt Macy if (RW_READ_HELD(rwlp)) 264eda14cbcSMatt Macy atomic_dec_uint(&rwlp->rw_readers); 265eda14cbcSMatt Macy else 266eda14cbcSMatt Macy rwlp->rw_owner = 0; 267eda14cbcSMatt Macy 268eda14cbcSMatt Macy VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock)); 269eda14cbcSMatt Macy } 270eda14cbcSMatt Macy 271eda14cbcSMatt Macy int 272eda14cbcSMatt Macy rw_tryenter(krwlock_t *rwlp, krw_t rw) 273eda14cbcSMatt Macy { 274eda14cbcSMatt Macy int error; 275eda14cbcSMatt Macy 276eda14cbcSMatt Macy if (rw == RW_READER) 277eda14cbcSMatt Macy error = pthread_rwlock_tryrdlock(&rwlp->rw_lock); 278eda14cbcSMatt Macy else 279eda14cbcSMatt Macy error = pthread_rwlock_trywrlock(&rwlp->rw_lock); 280eda14cbcSMatt Macy 281eda14cbcSMatt Macy if (error == 0) { 282eda14cbcSMatt Macy if (rw == RW_READER) 283eda14cbcSMatt Macy atomic_inc_uint(&rwlp->rw_readers); 284eda14cbcSMatt Macy else 285eda14cbcSMatt Macy rwlp->rw_owner = pthread_self(); 286eda14cbcSMatt Macy 287eda14cbcSMatt Macy return (1); 288eda14cbcSMatt Macy } 289eda14cbcSMatt Macy 290eda14cbcSMatt Macy VERIFY3S(error, ==, EBUSY); 291eda14cbcSMatt Macy 292eda14cbcSMatt Macy return (0); 293eda14cbcSMatt Macy } 294eda14cbcSMatt Macy 295eda14cbcSMatt Macy uint32_t 296eda14cbcSMatt Macy zone_get_hostid(void *zonep) 297eda14cbcSMatt Macy { 298eda14cbcSMatt Macy /* 299eda14cbcSMatt Macy * We're emulating the system's hostid in userland. 300eda14cbcSMatt Macy */ 301e92ffd9bSMartin Matuska (void) zonep; 302716fd348SMartin Matuska return (hostid); 303eda14cbcSMatt Macy } 304eda14cbcSMatt Macy 305eda14cbcSMatt Macy int 306eda14cbcSMatt Macy rw_tryupgrade(krwlock_t *rwlp) 307eda14cbcSMatt Macy { 308e92ffd9bSMartin Matuska (void) rwlp; 309eda14cbcSMatt Macy return (0); 310eda14cbcSMatt Macy } 311eda14cbcSMatt Macy 312eda14cbcSMatt Macy /* 313eda14cbcSMatt Macy * ========================================================================= 314eda14cbcSMatt Macy * condition variables 315eda14cbcSMatt Macy * ========================================================================= 316eda14cbcSMatt Macy */ 317eda14cbcSMatt Macy 318eda14cbcSMatt Macy void 319eda14cbcSMatt Macy cv_init(kcondvar_t *cv, char *name, int type, void *arg) 320eda14cbcSMatt Macy { 321e92ffd9bSMartin Matuska (void) name, (void) type, (void) arg; 322eda14cbcSMatt Macy VERIFY0(pthread_cond_init(cv, NULL)); 323eda14cbcSMatt Macy } 324eda14cbcSMatt Macy 325eda14cbcSMatt Macy void 326eda14cbcSMatt Macy cv_destroy(kcondvar_t *cv) 327eda14cbcSMatt Macy { 328eda14cbcSMatt Macy VERIFY0(pthread_cond_destroy(cv)); 329eda14cbcSMatt Macy } 330eda14cbcSMatt Macy 331eda14cbcSMatt Macy void 332eda14cbcSMatt Macy cv_wait(kcondvar_t *cv, kmutex_t *mp) 333eda14cbcSMatt Macy { 334eda14cbcSMatt Macy memset(&mp->m_owner, 0, sizeof (pthread_t)); 335eda14cbcSMatt Macy VERIFY0(pthread_cond_wait(cv, &mp->m_lock)); 336eda14cbcSMatt Macy mp->m_owner = pthread_self(); 337eda14cbcSMatt Macy } 338eda14cbcSMatt Macy 339eda14cbcSMatt Macy int 340eda14cbcSMatt Macy cv_wait_sig(kcondvar_t *cv, kmutex_t *mp) 341eda14cbcSMatt Macy { 342eda14cbcSMatt Macy cv_wait(cv, mp); 343eda14cbcSMatt Macy return (1); 344eda14cbcSMatt Macy } 345eda14cbcSMatt Macy 346eda14cbcSMatt Macy int 347eda14cbcSMatt Macy cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) 348eda14cbcSMatt Macy { 349eda14cbcSMatt Macy int error; 350eda14cbcSMatt Macy struct timeval tv; 351eda14cbcSMatt Macy struct timespec ts; 352eda14cbcSMatt Macy clock_t delta; 353eda14cbcSMatt Macy 354eda14cbcSMatt Macy delta = abstime - ddi_get_lbolt(); 355eda14cbcSMatt Macy if (delta <= 0) 356eda14cbcSMatt Macy return (-1); 357eda14cbcSMatt Macy 358eda14cbcSMatt Macy VERIFY(gettimeofday(&tv, NULL) == 0); 359eda14cbcSMatt Macy 360eda14cbcSMatt Macy ts.tv_sec = tv.tv_sec + delta / hz; 361eda14cbcSMatt Macy ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz); 362eda14cbcSMatt Macy if (ts.tv_nsec >= NANOSEC) { 363eda14cbcSMatt Macy ts.tv_sec++; 364eda14cbcSMatt Macy ts.tv_nsec -= NANOSEC; 365eda14cbcSMatt Macy } 366eda14cbcSMatt Macy 367eda14cbcSMatt Macy memset(&mp->m_owner, 0, sizeof (pthread_t)); 368eda14cbcSMatt Macy error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); 369eda14cbcSMatt Macy mp->m_owner = pthread_self(); 370eda14cbcSMatt Macy 371eda14cbcSMatt Macy if (error == ETIMEDOUT) 372eda14cbcSMatt Macy return (-1); 373eda14cbcSMatt Macy 374eda14cbcSMatt Macy VERIFY0(error); 375eda14cbcSMatt Macy 376eda14cbcSMatt Macy return (1); 377eda14cbcSMatt Macy } 378eda14cbcSMatt Macy 379eda14cbcSMatt Macy int 380eda14cbcSMatt Macy cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res, 381eda14cbcSMatt Macy int flag) 382eda14cbcSMatt Macy { 383e92ffd9bSMartin Matuska (void) res; 384eda14cbcSMatt Macy int error; 385eda14cbcSMatt Macy struct timeval tv; 386eda14cbcSMatt Macy struct timespec ts; 387eda14cbcSMatt Macy hrtime_t delta; 388eda14cbcSMatt Macy 389eda14cbcSMatt Macy ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE); 390eda14cbcSMatt Macy 391eda14cbcSMatt Macy delta = tim; 392eda14cbcSMatt Macy if (flag & CALLOUT_FLAG_ABSOLUTE) 393eda14cbcSMatt Macy delta -= gethrtime(); 394eda14cbcSMatt Macy 395eda14cbcSMatt Macy if (delta <= 0) 396eda14cbcSMatt Macy return (-1); 397eda14cbcSMatt Macy 398eda14cbcSMatt Macy VERIFY0(gettimeofday(&tv, NULL)); 399eda14cbcSMatt Macy 400eda14cbcSMatt Macy ts.tv_sec = tv.tv_sec + delta / NANOSEC; 401eda14cbcSMatt Macy ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC); 402eda14cbcSMatt Macy if (ts.tv_nsec >= NANOSEC) { 403eda14cbcSMatt Macy ts.tv_sec++; 404eda14cbcSMatt Macy ts.tv_nsec -= NANOSEC; 405eda14cbcSMatt Macy } 406eda14cbcSMatt Macy 407eda14cbcSMatt Macy memset(&mp->m_owner, 0, sizeof (pthread_t)); 408eda14cbcSMatt Macy error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); 409eda14cbcSMatt Macy mp->m_owner = pthread_self(); 410eda14cbcSMatt Macy 411eda14cbcSMatt Macy if (error == ETIMEDOUT) 412eda14cbcSMatt Macy return (-1); 413eda14cbcSMatt Macy 414eda14cbcSMatt Macy VERIFY0(error); 415eda14cbcSMatt Macy 416eda14cbcSMatt Macy return (1); 417eda14cbcSMatt Macy } 418eda14cbcSMatt Macy 419eda14cbcSMatt Macy void 420eda14cbcSMatt Macy cv_signal(kcondvar_t *cv) 421eda14cbcSMatt Macy { 422eda14cbcSMatt Macy VERIFY0(pthread_cond_signal(cv)); 423eda14cbcSMatt Macy } 424eda14cbcSMatt Macy 425eda14cbcSMatt Macy void 426eda14cbcSMatt Macy cv_broadcast(kcondvar_t *cv) 427eda14cbcSMatt Macy { 428eda14cbcSMatt Macy VERIFY0(pthread_cond_broadcast(cv)); 429eda14cbcSMatt Macy } 430eda14cbcSMatt Macy 431eda14cbcSMatt Macy /* 432eda14cbcSMatt Macy * ========================================================================= 433eda14cbcSMatt Macy * procfs list 434eda14cbcSMatt Macy * ========================================================================= 435eda14cbcSMatt Macy */ 436eda14cbcSMatt Macy 437eda14cbcSMatt Macy void 438eda14cbcSMatt Macy seq_printf(struct seq_file *m, const char *fmt, ...) 439e92ffd9bSMartin Matuska { 440e92ffd9bSMartin Matuska (void) m, (void) fmt; 441e92ffd9bSMartin Matuska } 442eda14cbcSMatt Macy 443eda14cbcSMatt Macy void 444eda14cbcSMatt Macy procfs_list_install(const char *module, 445c40487d4SMatt Macy const char *submodule, 446eda14cbcSMatt Macy const char *name, 447eda14cbcSMatt Macy mode_t mode, 448eda14cbcSMatt Macy procfs_list_t *procfs_list, 449eda14cbcSMatt Macy int (*show)(struct seq_file *f, void *p), 450eda14cbcSMatt Macy int (*show_header)(struct seq_file *f), 451eda14cbcSMatt Macy int (*clear)(procfs_list_t *procfs_list), 452eda14cbcSMatt Macy size_t procfs_list_node_off) 453eda14cbcSMatt Macy { 454e92ffd9bSMartin Matuska (void) module, (void) submodule, (void) name, (void) mode, (void) show, 455e92ffd9bSMartin Matuska (void) show_header, (void) clear; 456eda14cbcSMatt Macy mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL); 457eda14cbcSMatt Macy list_create(&procfs_list->pl_list, 458eda14cbcSMatt Macy procfs_list_node_off + sizeof (procfs_list_node_t), 459eda14cbcSMatt Macy procfs_list_node_off + offsetof(procfs_list_node_t, pln_link)); 460eda14cbcSMatt Macy procfs_list->pl_next_id = 1; 461eda14cbcSMatt Macy procfs_list->pl_node_offset = procfs_list_node_off; 462eda14cbcSMatt Macy } 463eda14cbcSMatt Macy 464eda14cbcSMatt Macy void 465eda14cbcSMatt Macy procfs_list_uninstall(procfs_list_t *procfs_list) 466e92ffd9bSMartin Matuska { 467e92ffd9bSMartin Matuska (void) procfs_list; 468e92ffd9bSMartin Matuska } 469eda14cbcSMatt Macy 470eda14cbcSMatt Macy void 471eda14cbcSMatt Macy procfs_list_destroy(procfs_list_t *procfs_list) 472eda14cbcSMatt Macy { 473eda14cbcSMatt Macy ASSERT(list_is_empty(&procfs_list->pl_list)); 474eda14cbcSMatt Macy list_destroy(&procfs_list->pl_list); 475eda14cbcSMatt Macy mutex_destroy(&procfs_list->pl_lock); 476eda14cbcSMatt Macy } 477eda14cbcSMatt Macy 478eda14cbcSMatt Macy #define NODE_ID(procfs_list, obj) \ 479eda14cbcSMatt Macy (((procfs_list_node_t *)(((char *)obj) + \ 480eda14cbcSMatt Macy (procfs_list)->pl_node_offset))->pln_id) 481eda14cbcSMatt Macy 482eda14cbcSMatt Macy void 483eda14cbcSMatt Macy procfs_list_add(procfs_list_t *procfs_list, void *p) 484eda14cbcSMatt Macy { 485eda14cbcSMatt Macy ASSERT(MUTEX_HELD(&procfs_list->pl_lock)); 486eda14cbcSMatt Macy NODE_ID(procfs_list, p) = procfs_list->pl_next_id++; 487eda14cbcSMatt Macy list_insert_tail(&procfs_list->pl_list, p); 488eda14cbcSMatt Macy } 489eda14cbcSMatt Macy 490eda14cbcSMatt Macy /* 491eda14cbcSMatt Macy * ========================================================================= 492eda14cbcSMatt Macy * vnode operations 493eda14cbcSMatt Macy * ========================================================================= 494eda14cbcSMatt Macy */ 495eda14cbcSMatt Macy 496eda14cbcSMatt Macy /* 497eda14cbcSMatt Macy * ========================================================================= 498eda14cbcSMatt Macy * Figure out which debugging statements to print 499eda14cbcSMatt Macy * ========================================================================= 500eda14cbcSMatt Macy */ 501eda14cbcSMatt Macy 502eda14cbcSMatt Macy static char *dprintf_string; 503eda14cbcSMatt Macy static int dprintf_print_all; 504eda14cbcSMatt Macy 505eda14cbcSMatt Macy int 506eda14cbcSMatt Macy dprintf_find_string(const char *string) 507eda14cbcSMatt Macy { 508eda14cbcSMatt Macy char *tmp_str = dprintf_string; 509eda14cbcSMatt Macy int len = strlen(string); 510eda14cbcSMatt Macy 511eda14cbcSMatt Macy /* 512eda14cbcSMatt Macy * Find out if this is a string we want to print. 513eda14cbcSMatt Macy * String format: file1.c,function_name1,file2.c,file3.c 514eda14cbcSMatt Macy */ 515eda14cbcSMatt Macy 516eda14cbcSMatt Macy while (tmp_str != NULL) { 517eda14cbcSMatt Macy if (strncmp(tmp_str, string, len) == 0 && 518eda14cbcSMatt Macy (tmp_str[len] == ',' || tmp_str[len] == '\0')) 519eda14cbcSMatt Macy return (1); 520eda14cbcSMatt Macy tmp_str = strchr(tmp_str, ','); 521eda14cbcSMatt Macy if (tmp_str != NULL) 522eda14cbcSMatt Macy tmp_str++; /* Get rid of , */ 523eda14cbcSMatt Macy } 524eda14cbcSMatt Macy return (0); 525eda14cbcSMatt Macy } 526eda14cbcSMatt Macy 527eda14cbcSMatt Macy void 528eda14cbcSMatt Macy dprintf_setup(int *argc, char **argv) 529eda14cbcSMatt Macy { 530eda14cbcSMatt Macy int i, j; 531eda14cbcSMatt Macy 532eda14cbcSMatt Macy /* 533eda14cbcSMatt Macy * Debugging can be specified two ways: by setting the 534eda14cbcSMatt Macy * environment variable ZFS_DEBUG, or by including a 535eda14cbcSMatt Macy * "debug=..." argument on the command line. The command 536eda14cbcSMatt Macy * line setting overrides the environment variable. 537eda14cbcSMatt Macy */ 538eda14cbcSMatt Macy 539eda14cbcSMatt Macy for (i = 1; i < *argc; i++) { 540eda14cbcSMatt Macy int len = strlen("debug="); 541eda14cbcSMatt Macy /* First look for a command line argument */ 542eda14cbcSMatt Macy if (strncmp("debug=", argv[i], len) == 0) { 543eda14cbcSMatt Macy dprintf_string = argv[i] + len; 544eda14cbcSMatt Macy /* Remove from args */ 545eda14cbcSMatt Macy for (j = i; j < *argc; j++) 546eda14cbcSMatt Macy argv[j] = argv[j+1]; 547eda14cbcSMatt Macy argv[j] = NULL; 548eda14cbcSMatt Macy (*argc)--; 549eda14cbcSMatt Macy } 550eda14cbcSMatt Macy } 551eda14cbcSMatt Macy 552eda14cbcSMatt Macy if (dprintf_string == NULL) { 553eda14cbcSMatt Macy /* Look for ZFS_DEBUG environment variable */ 554eda14cbcSMatt Macy dprintf_string = getenv("ZFS_DEBUG"); 555eda14cbcSMatt Macy } 556eda14cbcSMatt Macy 557eda14cbcSMatt Macy /* 558eda14cbcSMatt Macy * Are we just turning on all debugging? 559eda14cbcSMatt Macy */ 560eda14cbcSMatt Macy if (dprintf_find_string("on")) 561eda14cbcSMatt Macy dprintf_print_all = 1; 562eda14cbcSMatt Macy 563eda14cbcSMatt Macy if (dprintf_string != NULL) 564eda14cbcSMatt Macy zfs_flags |= ZFS_DEBUG_DPRINTF; 565eda14cbcSMatt Macy } 566eda14cbcSMatt Macy 567eda14cbcSMatt Macy /* 568eda14cbcSMatt Macy * ========================================================================= 569eda14cbcSMatt Macy * debug printfs 570eda14cbcSMatt Macy * ========================================================================= 571eda14cbcSMatt Macy */ 572eda14cbcSMatt Macy void 573eda14cbcSMatt Macy __dprintf(boolean_t dprint, const char *file, const char *func, 574eda14cbcSMatt Macy int line, const char *fmt, ...) 575eda14cbcSMatt Macy { 5763ff01b23SMartin Matuska /* Get rid of annoying "../common/" prefix to filename. */ 5773ff01b23SMartin Matuska const char *newfile = zfs_basename(file); 5783ff01b23SMartin Matuska 579eda14cbcSMatt Macy va_list adx; 580eda14cbcSMatt Macy if (dprint) { 581eda14cbcSMatt Macy /* dprintf messages are printed immediately */ 582eda14cbcSMatt Macy 583eda14cbcSMatt Macy if (!dprintf_print_all && 584eda14cbcSMatt Macy !dprintf_find_string(newfile) && 585eda14cbcSMatt Macy !dprintf_find_string(func)) 586eda14cbcSMatt Macy return; 587eda14cbcSMatt Macy 588eda14cbcSMatt Macy /* Print out just the function name if requested */ 589eda14cbcSMatt Macy flockfile(stdout); 590eda14cbcSMatt Macy if (dprintf_find_string("pid")) 591eda14cbcSMatt Macy (void) printf("%d ", getpid()); 592eda14cbcSMatt Macy if (dprintf_find_string("tid")) 593eda14cbcSMatt Macy (void) printf("%ju ", 594eda14cbcSMatt Macy (uintmax_t)(uintptr_t)pthread_self()); 595eda14cbcSMatt Macy if (dprintf_find_string("cpu")) 596eda14cbcSMatt Macy (void) printf("%u ", getcpuid()); 597eda14cbcSMatt Macy if (dprintf_find_string("time")) 598eda14cbcSMatt Macy (void) printf("%llu ", gethrtime()); 599eda14cbcSMatt Macy if (dprintf_find_string("long")) 600eda14cbcSMatt Macy (void) printf("%s, line %d: ", newfile, line); 601eda14cbcSMatt Macy (void) printf("dprintf: %s: ", func); 602eda14cbcSMatt Macy va_start(adx, fmt); 603eda14cbcSMatt Macy (void) vprintf(fmt, adx); 604eda14cbcSMatt Macy va_end(adx); 605eda14cbcSMatt Macy funlockfile(stdout); 606eda14cbcSMatt Macy } else { 607eda14cbcSMatt Macy /* zfs_dbgmsg is logged for dumping later */ 608eda14cbcSMatt Macy size_t size; 609eda14cbcSMatt Macy char *buf; 610eda14cbcSMatt Macy int i; 611eda14cbcSMatt Macy 612eda14cbcSMatt Macy size = 1024; 613eda14cbcSMatt Macy buf = umem_alloc(size, UMEM_NOFAIL); 614eda14cbcSMatt Macy i = snprintf(buf, size, "%s:%d:%s(): ", newfile, line, func); 615eda14cbcSMatt Macy 616eda14cbcSMatt Macy if (i < size) { 617eda14cbcSMatt Macy va_start(adx, fmt); 618eda14cbcSMatt Macy (void) vsnprintf(buf + i, size - i, fmt, adx); 619eda14cbcSMatt Macy va_end(adx); 620eda14cbcSMatt Macy } 621eda14cbcSMatt Macy 622eda14cbcSMatt Macy __zfs_dbgmsg(buf); 623eda14cbcSMatt Macy 624eda14cbcSMatt Macy umem_free(buf, size); 625eda14cbcSMatt Macy } 626eda14cbcSMatt Macy } 627eda14cbcSMatt Macy 628eda14cbcSMatt Macy /* 629eda14cbcSMatt Macy * ========================================================================= 630eda14cbcSMatt Macy * cmn_err() and panic() 631eda14cbcSMatt Macy * ========================================================================= 632eda14cbcSMatt Macy */ 633eda14cbcSMatt Macy static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" }; 634eda14cbcSMatt Macy static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" }; 635eda14cbcSMatt Macy 636da5137abSMartin Matuska __attribute__((noreturn)) void 637eda14cbcSMatt Macy vpanic(const char *fmt, va_list adx) 638eda14cbcSMatt Macy { 639eda14cbcSMatt Macy (void) fprintf(stderr, "error: "); 640eda14cbcSMatt Macy (void) vfprintf(stderr, fmt, adx); 641eda14cbcSMatt Macy (void) fprintf(stderr, "\n"); 642eda14cbcSMatt Macy 643eda14cbcSMatt Macy abort(); /* think of it as a "user-level crash dump" */ 644eda14cbcSMatt Macy } 645eda14cbcSMatt Macy 646da5137abSMartin Matuska __attribute__((noreturn)) void 647eda14cbcSMatt Macy panic(const char *fmt, ...) 648eda14cbcSMatt Macy { 649eda14cbcSMatt Macy va_list adx; 650eda14cbcSMatt Macy 651eda14cbcSMatt Macy va_start(adx, fmt); 652eda14cbcSMatt Macy vpanic(fmt, adx); 653eda14cbcSMatt Macy va_end(adx); 654eda14cbcSMatt Macy } 655eda14cbcSMatt Macy 656eda14cbcSMatt Macy void 657eda14cbcSMatt Macy vcmn_err(int ce, const char *fmt, va_list adx) 658eda14cbcSMatt Macy { 659eda14cbcSMatt Macy if (ce == CE_PANIC) 660eda14cbcSMatt Macy vpanic(fmt, adx); 661eda14cbcSMatt Macy if (ce != CE_NOTE) { /* suppress noise in userland stress testing */ 662eda14cbcSMatt Macy (void) fprintf(stderr, "%s", ce_prefix[ce]); 663eda14cbcSMatt Macy (void) vfprintf(stderr, fmt, adx); 664eda14cbcSMatt Macy (void) fprintf(stderr, "%s", ce_suffix[ce]); 665eda14cbcSMatt Macy } 666eda14cbcSMatt Macy } 667eda14cbcSMatt Macy 668eda14cbcSMatt Macy void 669eda14cbcSMatt Macy cmn_err(int ce, const char *fmt, ...) 670eda14cbcSMatt Macy { 671eda14cbcSMatt Macy va_list adx; 672eda14cbcSMatt Macy 673eda14cbcSMatt Macy va_start(adx, fmt); 674eda14cbcSMatt Macy vcmn_err(ce, fmt, adx); 675eda14cbcSMatt Macy va_end(adx); 676eda14cbcSMatt Macy } 677eda14cbcSMatt Macy 678eda14cbcSMatt Macy /* 679eda14cbcSMatt Macy * ========================================================================= 680eda14cbcSMatt Macy * misc routines 681eda14cbcSMatt Macy * ========================================================================= 682eda14cbcSMatt Macy */ 683eda14cbcSMatt Macy 684eda14cbcSMatt Macy void 685eda14cbcSMatt Macy delay(clock_t ticks) 686eda14cbcSMatt Macy { 687eda14cbcSMatt Macy (void) poll(0, 0, ticks * (1000 / hz)); 688eda14cbcSMatt Macy } 689eda14cbcSMatt Macy 690eda14cbcSMatt Macy /* 691eda14cbcSMatt Macy * Find highest one bit set. 692eda14cbcSMatt Macy * Returns bit number + 1 of highest bit that is set, otherwise returns 0. 693eda14cbcSMatt Macy * The __builtin_clzll() function is supported by both GCC and Clang. 694eda14cbcSMatt Macy */ 695eda14cbcSMatt Macy int 696eda14cbcSMatt Macy highbit64(uint64_t i) 697eda14cbcSMatt Macy { 698eda14cbcSMatt Macy if (i == 0) 699eda14cbcSMatt Macy return (0); 700eda14cbcSMatt Macy 701eda14cbcSMatt Macy return (NBBY * sizeof (uint64_t) - __builtin_clzll(i)); 702eda14cbcSMatt Macy } 703eda14cbcSMatt Macy 704eda14cbcSMatt Macy /* 705eda14cbcSMatt Macy * Find lowest one bit set. 706eda14cbcSMatt Macy * Returns bit number + 1 of lowest bit that is set, otherwise returns 0. 707eda14cbcSMatt Macy * The __builtin_ffsll() function is supported by both GCC and Clang. 708eda14cbcSMatt Macy */ 709eda14cbcSMatt Macy int 710eda14cbcSMatt Macy lowbit64(uint64_t i) 711eda14cbcSMatt Macy { 712eda14cbcSMatt Macy if (i == 0) 713eda14cbcSMatt Macy return (0); 714eda14cbcSMatt Macy 715eda14cbcSMatt Macy return (__builtin_ffsll(i)); 716eda14cbcSMatt Macy } 717eda14cbcSMatt Macy 71816038816SMartin Matuska const char *random_path = "/dev/random"; 71916038816SMartin Matuska const char *urandom_path = "/dev/urandom"; 720eda14cbcSMatt Macy static int random_fd = -1, urandom_fd = -1; 721eda14cbcSMatt Macy 722eda14cbcSMatt Macy void 723eda14cbcSMatt Macy random_init(void) 724eda14cbcSMatt Macy { 72516038816SMartin Matuska VERIFY((random_fd = open(random_path, O_RDONLY | O_CLOEXEC)) != -1); 72616038816SMartin Matuska VERIFY((urandom_fd = open(urandom_path, O_RDONLY | O_CLOEXEC)) != -1); 727eda14cbcSMatt Macy } 728eda14cbcSMatt Macy 729eda14cbcSMatt Macy void 730eda14cbcSMatt Macy random_fini(void) 731eda14cbcSMatt Macy { 732eda14cbcSMatt Macy close(random_fd); 733eda14cbcSMatt Macy close(urandom_fd); 734eda14cbcSMatt Macy 735eda14cbcSMatt Macy random_fd = -1; 736eda14cbcSMatt Macy urandom_fd = -1; 737eda14cbcSMatt Macy } 738eda14cbcSMatt Macy 739eda14cbcSMatt Macy static int 740eda14cbcSMatt Macy random_get_bytes_common(uint8_t *ptr, size_t len, int fd) 741eda14cbcSMatt Macy { 742eda14cbcSMatt Macy size_t resid = len; 743eda14cbcSMatt Macy ssize_t bytes; 744eda14cbcSMatt Macy 745eda14cbcSMatt Macy ASSERT(fd != -1); 746eda14cbcSMatt Macy 747eda14cbcSMatt Macy while (resid != 0) { 748eda14cbcSMatt Macy bytes = read(fd, ptr, resid); 749eda14cbcSMatt Macy ASSERT3S(bytes, >=, 0); 750eda14cbcSMatt Macy ptr += bytes; 751eda14cbcSMatt Macy resid -= bytes; 752eda14cbcSMatt Macy } 753eda14cbcSMatt Macy 754eda14cbcSMatt Macy return (0); 755eda14cbcSMatt Macy } 756eda14cbcSMatt Macy 757eda14cbcSMatt Macy int 758eda14cbcSMatt Macy random_get_bytes(uint8_t *ptr, size_t len) 759eda14cbcSMatt Macy { 760eda14cbcSMatt Macy return (random_get_bytes_common(ptr, len, random_fd)); 761eda14cbcSMatt Macy } 762eda14cbcSMatt Macy 763eda14cbcSMatt Macy int 764eda14cbcSMatt Macy random_get_pseudo_bytes(uint8_t *ptr, size_t len) 765eda14cbcSMatt Macy { 766eda14cbcSMatt Macy return (random_get_bytes_common(ptr, len, urandom_fd)); 767eda14cbcSMatt Macy } 768eda14cbcSMatt Macy 769eda14cbcSMatt Macy int 770eda14cbcSMatt Macy ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) 771eda14cbcSMatt Macy { 772e92ffd9bSMartin Matuska (void) nptr; 773eda14cbcSMatt Macy char *end; 774eda14cbcSMatt Macy 775eda14cbcSMatt Macy *result = strtoull(str, &end, base); 776eda14cbcSMatt Macy if (*result == 0) 777eda14cbcSMatt Macy return (errno); 778eda14cbcSMatt Macy return (0); 779eda14cbcSMatt Macy } 780eda14cbcSMatt Macy 781eda14cbcSMatt Macy utsname_t * 782eda14cbcSMatt Macy utsname(void) 783eda14cbcSMatt Macy { 784eda14cbcSMatt Macy return (&hw_utsname); 785eda14cbcSMatt Macy } 786eda14cbcSMatt Macy 787eda14cbcSMatt Macy /* 788eda14cbcSMatt Macy * ========================================================================= 789eda14cbcSMatt Macy * kernel emulation setup & teardown 790eda14cbcSMatt Macy * ========================================================================= 791eda14cbcSMatt Macy */ 792eda14cbcSMatt Macy static int 793eda14cbcSMatt Macy umem_out_of_memory(void) 794eda14cbcSMatt Macy { 795eda14cbcSMatt Macy char errmsg[] = "out of memory -- generating core dump\n"; 796eda14cbcSMatt Macy 797eda14cbcSMatt Macy (void) fprintf(stderr, "%s", errmsg); 798eda14cbcSMatt Macy abort(); 799eda14cbcSMatt Macy return (0); 800eda14cbcSMatt Macy } 801eda14cbcSMatt Macy 802eda14cbcSMatt Macy void 803eda14cbcSMatt Macy kernel_init(int mode) 804eda14cbcSMatt Macy { 805eda14cbcSMatt Macy extern uint_t rrw_tsd_key; 806eda14cbcSMatt Macy 807eda14cbcSMatt Macy umem_nofail_callback(umem_out_of_memory); 808eda14cbcSMatt Macy 809eda14cbcSMatt Macy physmem = sysconf(_SC_PHYS_PAGES); 810eda14cbcSMatt Macy 81133b8c039SMartin Matuska dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, 812eda14cbcSMatt Macy (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); 813eda14cbcSMatt Macy 814716fd348SMartin Matuska hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; 815eda14cbcSMatt Macy 816eda14cbcSMatt Macy random_init(); 817eda14cbcSMatt Macy 818eda14cbcSMatt Macy VERIFY0(uname(&hw_utsname)); 819eda14cbcSMatt Macy 820eda14cbcSMatt Macy system_taskq_init(); 821eda14cbcSMatt Macy icp_init(); 822eda14cbcSMatt Macy 823eda14cbcSMatt Macy zstd_init(); 824eda14cbcSMatt Macy 825eda14cbcSMatt Macy spa_init((spa_mode_t)mode); 826eda14cbcSMatt Macy 827eda14cbcSMatt Macy fletcher_4_init(); 828eda14cbcSMatt Macy 829eda14cbcSMatt Macy tsd_create(&rrw_tsd_key, rrw_tsd_destroy); 830eda14cbcSMatt Macy } 831eda14cbcSMatt Macy 832eda14cbcSMatt Macy void 833eda14cbcSMatt Macy kernel_fini(void) 834eda14cbcSMatt Macy { 835eda14cbcSMatt Macy fletcher_4_fini(); 836eda14cbcSMatt Macy spa_fini(); 837eda14cbcSMatt Macy 838eda14cbcSMatt Macy zstd_fini(); 839eda14cbcSMatt Macy 840eda14cbcSMatt Macy icp_fini(); 841eda14cbcSMatt Macy system_taskq_fini(); 842eda14cbcSMatt Macy 843eda14cbcSMatt Macy random_fini(); 844eda14cbcSMatt Macy } 845eda14cbcSMatt Macy 846eda14cbcSMatt Macy uid_t 847eda14cbcSMatt Macy crgetuid(cred_t *cr) 848eda14cbcSMatt Macy { 849e92ffd9bSMartin Matuska (void) cr; 850eda14cbcSMatt Macy return (0); 851eda14cbcSMatt Macy } 852eda14cbcSMatt Macy 853eda14cbcSMatt Macy uid_t 854eda14cbcSMatt Macy crgetruid(cred_t *cr) 855eda14cbcSMatt Macy { 856e92ffd9bSMartin Matuska (void) cr; 857eda14cbcSMatt Macy return (0); 858eda14cbcSMatt Macy } 859eda14cbcSMatt Macy 860eda14cbcSMatt Macy gid_t 861eda14cbcSMatt Macy crgetgid(cred_t *cr) 862eda14cbcSMatt Macy { 863e92ffd9bSMartin Matuska (void) cr; 864eda14cbcSMatt Macy return (0); 865eda14cbcSMatt Macy } 866eda14cbcSMatt Macy 867eda14cbcSMatt Macy int 868eda14cbcSMatt Macy crgetngroups(cred_t *cr) 869eda14cbcSMatt Macy { 870e92ffd9bSMartin Matuska (void) cr; 871eda14cbcSMatt Macy return (0); 872eda14cbcSMatt Macy } 873eda14cbcSMatt Macy 874eda14cbcSMatt Macy gid_t * 875eda14cbcSMatt Macy crgetgroups(cred_t *cr) 876eda14cbcSMatt Macy { 877e92ffd9bSMartin Matuska (void) cr; 878eda14cbcSMatt Macy return (NULL); 879eda14cbcSMatt Macy } 880eda14cbcSMatt Macy 881eda14cbcSMatt Macy int 882eda14cbcSMatt Macy zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) 883eda14cbcSMatt Macy { 884e92ffd9bSMartin Matuska (void) name, (void) cr; 885eda14cbcSMatt Macy return (0); 886eda14cbcSMatt Macy } 887eda14cbcSMatt Macy 888eda14cbcSMatt Macy int 889eda14cbcSMatt Macy zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) 890eda14cbcSMatt Macy { 891e92ffd9bSMartin Matuska (void) from, (void) to, (void) cr; 892eda14cbcSMatt Macy return (0); 893eda14cbcSMatt Macy } 894eda14cbcSMatt Macy 895eda14cbcSMatt Macy int 896eda14cbcSMatt Macy zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) 897eda14cbcSMatt Macy { 898e92ffd9bSMartin Matuska (void) name, (void) cr; 899eda14cbcSMatt Macy return (0); 900eda14cbcSMatt Macy } 901eda14cbcSMatt Macy 902eda14cbcSMatt Macy int 903eda14cbcSMatt Macy secpolicy_zfs(const cred_t *cr) 904eda14cbcSMatt Macy { 905e92ffd9bSMartin Matuska (void) cr; 906eda14cbcSMatt Macy return (0); 907eda14cbcSMatt Macy } 908eda14cbcSMatt Macy 909eda14cbcSMatt Macy int 910eda14cbcSMatt Macy secpolicy_zfs_proc(const cred_t *cr, proc_t *proc) 911eda14cbcSMatt Macy { 912e92ffd9bSMartin Matuska (void) cr, (void) proc; 913eda14cbcSMatt Macy return (0); 914eda14cbcSMatt Macy } 915eda14cbcSMatt Macy 916eda14cbcSMatt Macy ksiddomain_t * 917eda14cbcSMatt Macy ksid_lookupdomain(const char *dom) 918eda14cbcSMatt Macy { 919eda14cbcSMatt Macy ksiddomain_t *kd; 920eda14cbcSMatt Macy 921eda14cbcSMatt Macy kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL); 922eda14cbcSMatt Macy kd->kd_name = spa_strdup(dom); 923eda14cbcSMatt Macy return (kd); 924eda14cbcSMatt Macy } 925eda14cbcSMatt Macy 926eda14cbcSMatt Macy void 927eda14cbcSMatt Macy ksiddomain_rele(ksiddomain_t *ksid) 928eda14cbcSMatt Macy { 929eda14cbcSMatt Macy spa_strfree(ksid->kd_name); 930eda14cbcSMatt Macy umem_free(ksid, sizeof (ksiddomain_t)); 931eda14cbcSMatt Macy } 932eda14cbcSMatt Macy 933eda14cbcSMatt Macy char * 934eda14cbcSMatt Macy kmem_vasprintf(const char *fmt, va_list adx) 935eda14cbcSMatt Macy { 936eda14cbcSMatt Macy char *buf = NULL; 937eda14cbcSMatt Macy va_list adx_copy; 938eda14cbcSMatt Macy 939eda14cbcSMatt Macy va_copy(adx_copy, adx); 940eda14cbcSMatt Macy VERIFY(vasprintf(&buf, fmt, adx_copy) != -1); 941eda14cbcSMatt Macy va_end(adx_copy); 942eda14cbcSMatt Macy 943eda14cbcSMatt Macy return (buf); 944eda14cbcSMatt Macy } 945eda14cbcSMatt Macy 946eda14cbcSMatt Macy char * 947eda14cbcSMatt Macy kmem_asprintf(const char *fmt, ...) 948eda14cbcSMatt Macy { 949eda14cbcSMatt Macy char *buf = NULL; 950eda14cbcSMatt Macy va_list adx; 951eda14cbcSMatt Macy 952eda14cbcSMatt Macy va_start(adx, fmt); 953eda14cbcSMatt Macy VERIFY(vasprintf(&buf, fmt, adx) != -1); 954eda14cbcSMatt Macy va_end(adx); 955eda14cbcSMatt Macy 956eda14cbcSMatt Macy return (buf); 957eda14cbcSMatt Macy } 958eda14cbcSMatt Macy 959*dbd5678dSMartin Matuska /* 960*dbd5678dSMartin Matuska * kmem_scnprintf() will return the number of characters that it would have 961*dbd5678dSMartin Matuska * printed whenever it is limited by value of the size variable, rather than 962*dbd5678dSMartin Matuska * the number of characters that it did print. This can cause misbehavior on 963*dbd5678dSMartin Matuska * subsequent uses of the return value, so we define a safe version that will 964*dbd5678dSMartin Matuska * return the number of characters actually printed, minus the NULL format 965*dbd5678dSMartin Matuska * character. Subsequent use of this by the safe string functions is safe 966*dbd5678dSMartin Matuska * whether it is snprintf(), strlcat() or strlcpy(). 967*dbd5678dSMartin Matuska */ 968*dbd5678dSMartin Matuska int 969*dbd5678dSMartin Matuska kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...) 970*dbd5678dSMartin Matuska { 971*dbd5678dSMartin Matuska int n; 972*dbd5678dSMartin Matuska va_list ap; 973*dbd5678dSMartin Matuska 974*dbd5678dSMartin Matuska /* Make the 0 case a no-op so that we do not return -1 */ 975*dbd5678dSMartin Matuska if (size == 0) 976*dbd5678dSMartin Matuska return (0); 977*dbd5678dSMartin Matuska 978*dbd5678dSMartin Matuska va_start(ap, fmt); 979*dbd5678dSMartin Matuska n = vsnprintf(str, size, fmt, ap); 980*dbd5678dSMartin Matuska va_end(ap); 981*dbd5678dSMartin Matuska 982*dbd5678dSMartin Matuska if (n >= size) 983*dbd5678dSMartin Matuska n = size - 1; 984*dbd5678dSMartin Matuska 985*dbd5678dSMartin Matuska return (n); 986*dbd5678dSMartin Matuska } 987*dbd5678dSMartin Matuska 9885eb61f6cSMartin Matuska zfs_file_t * 989eda14cbcSMatt Macy zfs_onexit_fd_hold(int fd, minor_t *minorp) 990eda14cbcSMatt Macy { 991e92ffd9bSMartin Matuska (void) fd; 992eda14cbcSMatt Macy *minorp = 0; 9935eb61f6cSMartin Matuska return (NULL); 994eda14cbcSMatt Macy } 995eda14cbcSMatt Macy 996eda14cbcSMatt Macy void 9975eb61f6cSMartin Matuska zfs_onexit_fd_rele(zfs_file_t *fp) 998eda14cbcSMatt Macy { 999e92ffd9bSMartin Matuska (void) fp; 1000eda14cbcSMatt Macy } 1001eda14cbcSMatt Macy 1002eda14cbcSMatt Macy int 1003eda14cbcSMatt Macy zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, 1004*dbd5678dSMartin Matuska uintptr_t *action_handle) 1005eda14cbcSMatt Macy { 1006e92ffd9bSMartin Matuska (void) minor, (void) func, (void) data, (void) action_handle; 1007eda14cbcSMatt Macy return (0); 1008eda14cbcSMatt Macy } 1009eda14cbcSMatt Macy 1010eda14cbcSMatt Macy fstrans_cookie_t 1011eda14cbcSMatt Macy spl_fstrans_mark(void) 1012eda14cbcSMatt Macy { 1013eda14cbcSMatt Macy return ((fstrans_cookie_t)0); 1014eda14cbcSMatt Macy } 1015eda14cbcSMatt Macy 1016eda14cbcSMatt Macy void 1017eda14cbcSMatt Macy spl_fstrans_unmark(fstrans_cookie_t cookie) 1018eda14cbcSMatt Macy { 1019e92ffd9bSMartin Matuska (void) cookie; 1020eda14cbcSMatt Macy } 1021eda14cbcSMatt Macy 1022eda14cbcSMatt Macy int 1023eda14cbcSMatt Macy __spl_pf_fstrans_check(void) 1024eda14cbcSMatt Macy { 1025eda14cbcSMatt Macy return (0); 1026eda14cbcSMatt Macy } 1027eda14cbcSMatt Macy 1028eda14cbcSMatt Macy int 1029eda14cbcSMatt Macy kmem_cache_reap_active(void) 1030eda14cbcSMatt Macy { 1031eda14cbcSMatt Macy return (0); 1032eda14cbcSMatt Macy } 1033eda14cbcSMatt Macy 1034eda14cbcSMatt Macy void 1035eda14cbcSMatt Macy zvol_create_minor(const char *name) 1036eda14cbcSMatt Macy { 1037e92ffd9bSMartin Matuska (void) name; 1038eda14cbcSMatt Macy } 1039eda14cbcSMatt Macy 1040eda14cbcSMatt Macy void 1041eda14cbcSMatt Macy zvol_create_minors_recursive(const char *name) 1042eda14cbcSMatt Macy { 1043e92ffd9bSMartin Matuska (void) name; 1044eda14cbcSMatt Macy } 1045eda14cbcSMatt Macy 1046eda14cbcSMatt Macy void 1047eda14cbcSMatt Macy zvol_remove_minors(spa_t *spa, const char *name, boolean_t async) 1048eda14cbcSMatt Macy { 1049e92ffd9bSMartin Matuska (void) spa, (void) name, (void) async; 1050eda14cbcSMatt Macy } 1051eda14cbcSMatt Macy 1052eda14cbcSMatt Macy void 1053eda14cbcSMatt Macy zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname, 1054eda14cbcSMatt Macy boolean_t async) 1055eda14cbcSMatt Macy { 1056e92ffd9bSMartin Matuska (void) spa, (void) oldname, (void) newname, (void) async; 1057eda14cbcSMatt Macy } 1058eda14cbcSMatt Macy 1059eda14cbcSMatt Macy /* 1060eda14cbcSMatt Macy * Open file 1061eda14cbcSMatt Macy * 1062eda14cbcSMatt Macy * path - fully qualified path to file 1063eda14cbcSMatt Macy * flags - file attributes O_READ / O_WRITE / O_EXCL 1064eda14cbcSMatt Macy * fpp - pointer to return file pointer 1065eda14cbcSMatt Macy * 1066eda14cbcSMatt Macy * Returns 0 on success underlying error on failure. 1067eda14cbcSMatt Macy */ 1068eda14cbcSMatt Macy int 1069eda14cbcSMatt Macy zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp) 1070eda14cbcSMatt Macy { 1071eda14cbcSMatt Macy int fd = -1; 1072eda14cbcSMatt Macy int dump_fd = -1; 1073eda14cbcSMatt Macy int err; 1074eda14cbcSMatt Macy int old_umask = 0; 1075eda14cbcSMatt Macy zfs_file_t *fp; 1076eda14cbcSMatt Macy struct stat64 st; 1077eda14cbcSMatt Macy 1078eda14cbcSMatt Macy if (!(flags & O_CREAT) && stat64(path, &st) == -1) 1079eda14cbcSMatt Macy return (errno); 1080eda14cbcSMatt Macy 1081eda14cbcSMatt Macy if (!(flags & O_CREAT) && S_ISBLK(st.st_mode)) 1082eda14cbcSMatt Macy flags |= O_DIRECT; 1083eda14cbcSMatt Macy 1084eda14cbcSMatt Macy if (flags & O_CREAT) 1085eda14cbcSMatt Macy old_umask = umask(0); 1086eda14cbcSMatt Macy 1087eda14cbcSMatt Macy fd = open64(path, flags, mode); 1088eda14cbcSMatt Macy if (fd == -1) 1089eda14cbcSMatt Macy return (errno); 1090eda14cbcSMatt Macy 1091eda14cbcSMatt Macy if (flags & O_CREAT) 1092eda14cbcSMatt Macy (void) umask(old_umask); 1093eda14cbcSMatt Macy 1094eda14cbcSMatt Macy if (vn_dumpdir != NULL) { 1095eda14cbcSMatt Macy char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL); 10963ff01b23SMartin Matuska const char *inpath = zfs_basename(path); 1097eda14cbcSMatt Macy 1098eda14cbcSMatt Macy (void) snprintf(dumppath, MAXPATHLEN, 1099eda14cbcSMatt Macy "%s/%s", vn_dumpdir, inpath); 1100eda14cbcSMatt Macy dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666); 1101eda14cbcSMatt Macy umem_free(dumppath, MAXPATHLEN); 1102eda14cbcSMatt Macy if (dump_fd == -1) { 1103eda14cbcSMatt Macy err = errno; 1104eda14cbcSMatt Macy close(fd); 1105eda14cbcSMatt Macy return (err); 1106eda14cbcSMatt Macy } 1107eda14cbcSMatt Macy } else { 1108eda14cbcSMatt Macy dump_fd = -1; 1109eda14cbcSMatt Macy } 1110eda14cbcSMatt Macy 1111eda14cbcSMatt Macy (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 1112eda14cbcSMatt Macy 1113eda14cbcSMatt Macy fp = umem_zalloc(sizeof (zfs_file_t), UMEM_NOFAIL); 1114eda14cbcSMatt Macy fp->f_fd = fd; 1115eda14cbcSMatt Macy fp->f_dump_fd = dump_fd; 1116eda14cbcSMatt Macy *fpp = fp; 1117eda14cbcSMatt Macy 1118eda14cbcSMatt Macy return (0); 1119eda14cbcSMatt Macy } 1120eda14cbcSMatt Macy 1121eda14cbcSMatt Macy void 1122eda14cbcSMatt Macy zfs_file_close(zfs_file_t *fp) 1123eda14cbcSMatt Macy { 1124eda14cbcSMatt Macy close(fp->f_fd); 1125eda14cbcSMatt Macy if (fp->f_dump_fd != -1) 1126eda14cbcSMatt Macy close(fp->f_dump_fd); 1127eda14cbcSMatt Macy 1128eda14cbcSMatt Macy umem_free(fp, sizeof (zfs_file_t)); 1129eda14cbcSMatt Macy } 1130eda14cbcSMatt Macy 1131eda14cbcSMatt Macy /* 1132eda14cbcSMatt Macy * Stateful write - use os internal file pointer to determine where to 1133eda14cbcSMatt Macy * write and update on successful completion. 1134eda14cbcSMatt Macy * 1135eda14cbcSMatt Macy * fp - pointer to file (pipe, socket, etc) to write to 1136eda14cbcSMatt Macy * buf - buffer to write 1137eda14cbcSMatt Macy * count - # of bytes to write 1138eda14cbcSMatt Macy * resid - pointer to count of unwritten bytes (if short write) 1139eda14cbcSMatt Macy * 1140eda14cbcSMatt Macy * Returns 0 on success errno on failure. 1141eda14cbcSMatt Macy */ 1142eda14cbcSMatt Macy int 1143eda14cbcSMatt Macy zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid) 1144eda14cbcSMatt Macy { 1145eda14cbcSMatt Macy ssize_t rc; 1146eda14cbcSMatt Macy 1147eda14cbcSMatt Macy rc = write(fp->f_fd, buf, count); 1148eda14cbcSMatt Macy if (rc < 0) 1149eda14cbcSMatt Macy return (errno); 1150eda14cbcSMatt Macy 1151eda14cbcSMatt Macy if (resid) { 1152eda14cbcSMatt Macy *resid = count - rc; 1153eda14cbcSMatt Macy } else if (rc != count) { 1154eda14cbcSMatt Macy return (EIO); 1155eda14cbcSMatt Macy } 1156eda14cbcSMatt Macy 1157eda14cbcSMatt Macy return (0); 1158eda14cbcSMatt Macy } 1159eda14cbcSMatt Macy 1160eda14cbcSMatt Macy /* 1161eda14cbcSMatt Macy * Stateless write - os internal file pointer is not updated. 1162eda14cbcSMatt Macy * 1163eda14cbcSMatt Macy * fp - pointer to file (pipe, socket, etc) to write to 1164eda14cbcSMatt Macy * buf - buffer to write 1165eda14cbcSMatt Macy * count - # of bytes to write 1166eda14cbcSMatt Macy * off - file offset to write to (only valid for seekable types) 1167eda14cbcSMatt Macy * resid - pointer to count of unwritten bytes 1168eda14cbcSMatt Macy * 1169eda14cbcSMatt Macy * Returns 0 on success errno on failure. 1170eda14cbcSMatt Macy */ 1171eda14cbcSMatt Macy int 1172eda14cbcSMatt Macy zfs_file_pwrite(zfs_file_t *fp, const void *buf, 1173eda14cbcSMatt Macy size_t count, loff_t pos, ssize_t *resid) 1174eda14cbcSMatt Macy { 1175eda14cbcSMatt Macy ssize_t rc, split, done; 1176eda14cbcSMatt Macy int sectors; 1177eda14cbcSMatt Macy 1178eda14cbcSMatt Macy /* 1179eda14cbcSMatt Macy * To simulate partial disk writes, we split writes into two 1180eda14cbcSMatt Macy * system calls so that the process can be killed in between. 1181eda14cbcSMatt Macy * This is used by ztest to simulate realistic failure modes. 1182eda14cbcSMatt Macy */ 1183eda14cbcSMatt Macy sectors = count >> SPA_MINBLOCKSHIFT; 1184eda14cbcSMatt Macy split = (sectors > 0 ? rand() % sectors : 0) << SPA_MINBLOCKSHIFT; 1185eda14cbcSMatt Macy rc = pwrite64(fp->f_fd, buf, split, pos); 1186eda14cbcSMatt Macy if (rc != -1) { 1187eda14cbcSMatt Macy done = rc; 1188eda14cbcSMatt Macy rc = pwrite64(fp->f_fd, (char *)buf + split, 1189eda14cbcSMatt Macy count - split, pos + split); 1190eda14cbcSMatt Macy } 1191eda14cbcSMatt Macy #ifdef __linux__ 1192eda14cbcSMatt Macy if (rc == -1 && errno == EINVAL) { 1193eda14cbcSMatt Macy /* 1194eda14cbcSMatt Macy * Under Linux, this most likely means an alignment issue 1195eda14cbcSMatt Macy * (memory or disk) due to O_DIRECT, so we abort() in order 1196eda14cbcSMatt Macy * to catch the offender. 1197eda14cbcSMatt Macy */ 1198eda14cbcSMatt Macy abort(); 1199eda14cbcSMatt Macy } 1200eda14cbcSMatt Macy #endif 1201eda14cbcSMatt Macy 1202eda14cbcSMatt Macy if (rc < 0) 1203eda14cbcSMatt Macy return (errno); 1204eda14cbcSMatt Macy 1205eda14cbcSMatt Macy done += rc; 1206eda14cbcSMatt Macy 1207eda14cbcSMatt Macy if (resid) { 1208eda14cbcSMatt Macy *resid = count - done; 1209eda14cbcSMatt Macy } else if (done != count) { 1210eda14cbcSMatt Macy return (EIO); 1211eda14cbcSMatt Macy } 1212eda14cbcSMatt Macy 1213eda14cbcSMatt Macy return (0); 1214eda14cbcSMatt Macy } 1215eda14cbcSMatt Macy 1216eda14cbcSMatt Macy /* 1217eda14cbcSMatt Macy * Stateful read - use os internal file pointer to determine where to 1218eda14cbcSMatt Macy * read and update on successful completion. 1219eda14cbcSMatt Macy * 1220eda14cbcSMatt Macy * fp - pointer to file (pipe, socket, etc) to read from 1221eda14cbcSMatt Macy * buf - buffer to write 1222eda14cbcSMatt Macy * count - # of bytes to read 1223eda14cbcSMatt Macy * resid - pointer to count of unread bytes (if short read) 1224eda14cbcSMatt Macy * 1225eda14cbcSMatt Macy * Returns 0 on success errno on failure. 1226eda14cbcSMatt Macy */ 1227eda14cbcSMatt Macy int 1228eda14cbcSMatt Macy zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid) 1229eda14cbcSMatt Macy { 1230eda14cbcSMatt Macy int rc; 1231eda14cbcSMatt Macy 1232eda14cbcSMatt Macy rc = read(fp->f_fd, buf, count); 1233eda14cbcSMatt Macy if (rc < 0) 1234eda14cbcSMatt Macy return (errno); 1235eda14cbcSMatt Macy 1236eda14cbcSMatt Macy if (resid) { 1237eda14cbcSMatt Macy *resid = count - rc; 1238eda14cbcSMatt Macy } else if (rc != count) { 1239eda14cbcSMatt Macy return (EIO); 1240eda14cbcSMatt Macy } 1241eda14cbcSMatt Macy 1242eda14cbcSMatt Macy return (0); 1243eda14cbcSMatt Macy } 1244eda14cbcSMatt Macy 1245eda14cbcSMatt Macy /* 1246eda14cbcSMatt Macy * Stateless read - os internal file pointer is not updated. 1247eda14cbcSMatt Macy * 1248eda14cbcSMatt Macy * fp - pointer to file (pipe, socket, etc) to read from 1249eda14cbcSMatt Macy * buf - buffer to write 1250eda14cbcSMatt Macy * count - # of bytes to write 1251eda14cbcSMatt Macy * off - file offset to read from (only valid for seekable types) 1252eda14cbcSMatt Macy * resid - pointer to count of unwritten bytes (if short write) 1253eda14cbcSMatt Macy * 1254eda14cbcSMatt Macy * Returns 0 on success errno on failure. 1255eda14cbcSMatt Macy */ 1256eda14cbcSMatt Macy int 1257eda14cbcSMatt Macy zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off, 1258eda14cbcSMatt Macy ssize_t *resid) 1259eda14cbcSMatt Macy { 1260eda14cbcSMatt Macy ssize_t rc; 1261eda14cbcSMatt Macy 1262eda14cbcSMatt Macy rc = pread64(fp->f_fd, buf, count, off); 1263eda14cbcSMatt Macy if (rc < 0) { 1264eda14cbcSMatt Macy #ifdef __linux__ 1265eda14cbcSMatt Macy /* 1266eda14cbcSMatt Macy * Under Linux, this most likely means an alignment issue 1267eda14cbcSMatt Macy * (memory or disk) due to O_DIRECT, so we abort() in order to 1268eda14cbcSMatt Macy * catch the offender. 1269eda14cbcSMatt Macy */ 1270eda14cbcSMatt Macy if (errno == EINVAL) 1271eda14cbcSMatt Macy abort(); 1272eda14cbcSMatt Macy #endif 1273eda14cbcSMatt Macy return (errno); 1274eda14cbcSMatt Macy } 1275eda14cbcSMatt Macy 1276eda14cbcSMatt Macy if (fp->f_dump_fd != -1) { 1277eda14cbcSMatt Macy int status; 1278eda14cbcSMatt Macy 1279eda14cbcSMatt Macy status = pwrite64(fp->f_dump_fd, buf, rc, off); 1280eda14cbcSMatt Macy ASSERT(status != -1); 1281eda14cbcSMatt Macy } 1282eda14cbcSMatt Macy 1283eda14cbcSMatt Macy if (resid) { 1284eda14cbcSMatt Macy *resid = count - rc; 1285eda14cbcSMatt Macy } else if (rc != count) { 1286eda14cbcSMatt Macy return (EIO); 1287eda14cbcSMatt Macy } 1288eda14cbcSMatt Macy 1289eda14cbcSMatt Macy return (0); 1290eda14cbcSMatt Macy } 1291eda14cbcSMatt Macy 1292eda14cbcSMatt Macy /* 1293eda14cbcSMatt Macy * lseek - set / get file pointer 1294eda14cbcSMatt Macy * 1295eda14cbcSMatt Macy * fp - pointer to file (pipe, socket, etc) to read from 1296eda14cbcSMatt Macy * offp - value to seek to, returns current value plus passed offset 1297eda14cbcSMatt Macy * whence - see man pages for standard lseek whence values 1298eda14cbcSMatt Macy * 1299eda14cbcSMatt Macy * Returns 0 on success errno on failure (ESPIPE for non seekable types) 1300eda14cbcSMatt Macy */ 1301eda14cbcSMatt Macy int 1302eda14cbcSMatt Macy zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence) 1303eda14cbcSMatt Macy { 1304eda14cbcSMatt Macy loff_t rc; 1305eda14cbcSMatt Macy 1306eda14cbcSMatt Macy rc = lseek(fp->f_fd, *offp, whence); 1307eda14cbcSMatt Macy if (rc < 0) 1308eda14cbcSMatt Macy return (errno); 1309eda14cbcSMatt Macy 1310eda14cbcSMatt Macy *offp = rc; 1311eda14cbcSMatt Macy 1312eda14cbcSMatt Macy return (0); 1313eda14cbcSMatt Macy } 1314eda14cbcSMatt Macy 1315eda14cbcSMatt Macy /* 1316eda14cbcSMatt Macy * Get file attributes 1317eda14cbcSMatt Macy * 1318eda14cbcSMatt Macy * filp - file pointer 1319eda14cbcSMatt Macy * zfattr - pointer to file attr structure 1320eda14cbcSMatt Macy * 1321eda14cbcSMatt Macy * Currently only used for fetching size and file mode 1322eda14cbcSMatt Macy * 1323eda14cbcSMatt Macy * Returns 0 on success or error code of underlying getattr call on failure. 1324eda14cbcSMatt Macy */ 1325eda14cbcSMatt Macy int 1326eda14cbcSMatt Macy zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr) 1327eda14cbcSMatt Macy { 1328eda14cbcSMatt Macy struct stat64 st; 1329eda14cbcSMatt Macy 1330eda14cbcSMatt Macy if (fstat64_blk(fp->f_fd, &st) == -1) 1331eda14cbcSMatt Macy return (errno); 1332eda14cbcSMatt Macy 1333eda14cbcSMatt Macy zfattr->zfa_size = st.st_size; 1334eda14cbcSMatt Macy zfattr->zfa_mode = st.st_mode; 1335eda14cbcSMatt Macy 1336eda14cbcSMatt Macy return (0); 1337eda14cbcSMatt Macy } 1338eda14cbcSMatt Macy 1339eda14cbcSMatt Macy /* 1340eda14cbcSMatt Macy * Sync file to disk 1341eda14cbcSMatt Macy * 1342eda14cbcSMatt Macy * filp - file pointer 1343eda14cbcSMatt Macy * flags - O_SYNC and or O_DSYNC 1344eda14cbcSMatt Macy * 1345eda14cbcSMatt Macy * Returns 0 on success or error code of underlying sync call on failure. 1346eda14cbcSMatt Macy */ 1347eda14cbcSMatt Macy int 1348eda14cbcSMatt Macy zfs_file_fsync(zfs_file_t *fp, int flags) 1349eda14cbcSMatt Macy { 1350e92ffd9bSMartin Matuska (void) flags; 1351eda14cbcSMatt Macy 1352e92ffd9bSMartin Matuska if (fsync(fp->f_fd) < 0) 1353eda14cbcSMatt Macy return (errno); 1354eda14cbcSMatt Macy 1355eda14cbcSMatt Macy return (0); 1356eda14cbcSMatt Macy } 1357eda14cbcSMatt Macy 1358eda14cbcSMatt Macy /* 1359eda14cbcSMatt Macy * fallocate - allocate or free space on disk 1360eda14cbcSMatt Macy * 1361eda14cbcSMatt Macy * fp - file pointer 1362eda14cbcSMatt Macy * mode (non-standard options for hole punching etc) 1363eda14cbcSMatt Macy * offset - offset to start allocating or freeing from 1364eda14cbcSMatt Macy * len - length to free / allocate 1365eda14cbcSMatt Macy * 1366eda14cbcSMatt Macy * OPTIONAL 1367eda14cbcSMatt Macy */ 1368eda14cbcSMatt Macy int 1369eda14cbcSMatt Macy zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len) 1370eda14cbcSMatt Macy { 1371eda14cbcSMatt Macy #ifdef __linux__ 1372eda14cbcSMatt Macy return (fallocate(fp->f_fd, mode, offset, len)); 1373eda14cbcSMatt Macy #else 1374e92ffd9bSMartin Matuska (void) fp, (void) mode, (void) offset, (void) len; 1375eda14cbcSMatt Macy return (EOPNOTSUPP); 1376eda14cbcSMatt Macy #endif 1377eda14cbcSMatt Macy } 1378eda14cbcSMatt Macy 1379eda14cbcSMatt Macy /* 1380eda14cbcSMatt Macy * Request current file pointer offset 1381eda14cbcSMatt Macy * 1382eda14cbcSMatt Macy * fp - pointer to file 1383eda14cbcSMatt Macy * 1384eda14cbcSMatt Macy * Returns current file offset. 1385eda14cbcSMatt Macy */ 1386eda14cbcSMatt Macy loff_t 1387eda14cbcSMatt Macy zfs_file_off(zfs_file_t *fp) 1388eda14cbcSMatt Macy { 1389eda14cbcSMatt Macy return (lseek(fp->f_fd, SEEK_CUR, 0)); 1390eda14cbcSMatt Macy } 1391eda14cbcSMatt Macy 1392eda14cbcSMatt Macy /* 1393eda14cbcSMatt Macy * unlink file 1394eda14cbcSMatt Macy * 1395eda14cbcSMatt Macy * path - fully qualified file path 1396eda14cbcSMatt Macy * 1397eda14cbcSMatt Macy * Returns 0 on success. 1398eda14cbcSMatt Macy * 1399eda14cbcSMatt Macy * OPTIONAL 1400eda14cbcSMatt Macy */ 1401eda14cbcSMatt Macy int 1402eda14cbcSMatt Macy zfs_file_unlink(const char *path) 1403eda14cbcSMatt Macy { 1404eda14cbcSMatt Macy return (remove(path)); 1405eda14cbcSMatt Macy } 1406eda14cbcSMatt Macy 1407eda14cbcSMatt Macy /* 1408eda14cbcSMatt Macy * Get reference to file pointer 1409eda14cbcSMatt Macy * 1410eda14cbcSMatt Macy * fd - input file descriptor 1411eda14cbcSMatt Macy * 14125eb61f6cSMartin Matuska * Returns pointer to file struct or NULL. 1413eda14cbcSMatt Macy * Unsupported in user space. 1414eda14cbcSMatt Macy */ 14155eb61f6cSMartin Matuska zfs_file_t * 14165eb61f6cSMartin Matuska zfs_file_get(int fd) 1417eda14cbcSMatt Macy { 1418e92ffd9bSMartin Matuska (void) fd; 1419eda14cbcSMatt Macy abort(); 14205eb61f6cSMartin Matuska return (NULL); 1421eda14cbcSMatt Macy } 1422eda14cbcSMatt Macy /* 1423eda14cbcSMatt Macy * Drop reference to file pointer 1424eda14cbcSMatt Macy * 14255eb61f6cSMartin Matuska * fp - pointer to file struct 1426eda14cbcSMatt Macy * 1427eda14cbcSMatt Macy * Unsupported in user space. 1428eda14cbcSMatt Macy */ 1429eda14cbcSMatt Macy void 14305eb61f6cSMartin Matuska zfs_file_put(zfs_file_t *fp) 1431eda14cbcSMatt Macy { 1432eda14cbcSMatt Macy abort(); 1433e92ffd9bSMartin Matuska (void) fp; 1434eda14cbcSMatt Macy } 1435eac7052fSMatt Macy 1436eac7052fSMatt Macy void 1437eac7052fSMatt Macy zfsvfs_update_fromname(const char *oldname, const char *newname) 1438eac7052fSMatt Macy { 1439e92ffd9bSMartin Matuska (void) oldname, (void) newname; 1440eac7052fSMatt Macy } 1441c03c5b1cSMartin Matuska 1442c03c5b1cSMartin Matuska void 1443c03c5b1cSMartin Matuska spa_import_os(spa_t *spa) 1444c03c5b1cSMartin Matuska { 1445c03c5b1cSMartin Matuska (void) spa; 1446c03c5b1cSMartin Matuska } 1447c03c5b1cSMartin Matuska 1448c03c5b1cSMartin Matuska void 1449c03c5b1cSMartin Matuska spa_export_os(spa_t *spa) 1450c03c5b1cSMartin Matuska { 1451c03c5b1cSMartin Matuska (void) spa; 1452c03c5b1cSMartin Matuska } 1453c03c5b1cSMartin Matuska 1454c03c5b1cSMartin Matuska void 1455c03c5b1cSMartin Matuska spa_activate_os(spa_t *spa) 1456c03c5b1cSMartin Matuska { 1457c03c5b1cSMartin Matuska (void) spa; 1458c03c5b1cSMartin Matuska } 1459c03c5b1cSMartin Matuska 1460c03c5b1cSMartin Matuska void 1461c03c5b1cSMartin Matuska spa_deactivate_os(spa_t *spa) 1462c03c5b1cSMartin Matuska { 1463c03c5b1cSMartin Matuska (void) spa; 1464c03c5b1cSMartin Matuska } 1465