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