diff options
Diffstat (limited to 'lib/libzpool')
-rw-r--r-- | lib/libzpool/Makefile.am | 220 | ||||
-rw-r--r-- | lib/libzpool/abd_os.c | 430 | ||||
-rw-r--r-- | lib/libzpool/arc_os.c | 88 | ||||
-rw-r--r-- | lib/libzpool/kernel.c | 1540 | ||||
-rw-r--r-- | lib/libzpool/taskq.c | 417 | ||||
-rw-r--r-- | lib/libzpool/util.c | 383 | ||||
-rw-r--r-- | lib/libzpool/vdev_label_os.c | 52 | ||||
-rw-r--r-- | lib/libzpool/zfs_debug.c | 125 | ||||
-rw-r--r-- | lib/libzpool/zfs_racct.c | 39 |
9 files changed, 0 insertions, 3294 deletions
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am deleted file mode 100644 index aeacc595b363..000000000000 --- a/lib/libzpool/Makefile.am +++ /dev/null @@ -1,220 +0,0 @@ -libzpool_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) -libzpool_la_CFLAGS += $(ZLIB_CFLAGS) - -libzpool_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) -libzpool_la_CPPFLAGS += -I$(srcdir)/include/os/@ac_system_l@/zfs -libzpool_la_CPPFLAGS += -DLIB_ZPOOL_BUILD - -lib_LTLIBRARIES += libzpool.la -CPPCHECKTARGETS += libzpool.la - -dist_libzpool_la_SOURCES = \ - %D%/abd_os.c \ - %D%/arc_os.c \ - %D%/kernel.c \ - %D%/taskq.c \ - %D%/util.c \ - %D%/vdev_label_os.c \ - %D%/zfs_racct.c \ - %D%/zfs_debug.c - -nodist_libzpool_la_SOURCES = \ - module/lua/lapi.c \ - module/lua/lauxlib.c \ - module/lua/lbaselib.c \ - module/lua/lcode.c \ - module/lua/lcompat.c \ - module/lua/lcorolib.c \ - module/lua/lctype.c \ - module/lua/ldebug.c \ - module/lua/ldo.c \ - module/lua/lfunc.c \ - module/lua/lgc.c \ - module/lua/llex.c \ - module/lua/lmem.c \ - module/lua/lobject.c \ - module/lua/lopcodes.c \ - module/lua/lparser.c \ - module/lua/lstate.c \ - module/lua/lstring.c \ - module/lua/lstrlib.c \ - module/lua/ltable.c \ - module/lua/ltablib.c \ - module/lua/ltm.c \ - module/lua/lvm.c \ - module/lua/lzio.c \ - \ - module/os/linux/zfs/zio_crypt.c \ - \ - module/zcommon/cityhash.c \ - module/zcommon/simd_stat.c \ - module/zcommon/zfeature_common.c \ - module/zcommon/zfs_comutil.c \ - module/zcommon/zfs_deleg.c \ - module/zcommon/zfs_fletcher.c \ - module/zcommon/zfs_fletcher_aarch64_neon.c \ - module/zcommon/zfs_fletcher_avx512.c \ - module/zcommon/zfs_fletcher_intel.c \ - module/zcommon/zfs_fletcher_sse.c \ - module/zcommon/zfs_fletcher_superscalar.c \ - module/zcommon/zfs_fletcher_superscalar4.c \ - module/zcommon/zfs_namecheck.c \ - module/zcommon/zfs_prop.c \ - module/zcommon/zfs_valstr.c \ - module/zcommon/zpool_prop.c \ - module/zcommon/zprop_common.c \ - \ - module/zfs/abd.c \ - module/zfs/aggsum.c \ - module/zfs/arc.c \ - module/zfs/blake3_zfs.c \ - module/zfs/blkptr.c \ - module/zfs/bplist.c \ - module/zfs/bpobj.c \ - module/zfs/bptree.c \ - module/zfs/bqueue.c \ - module/zfs/btree.c \ - module/zfs/brt.c \ - module/zfs/dbuf.c \ - module/zfs/dbuf_stats.c \ - module/zfs/ddt.c \ - module/zfs/ddt_log.c \ - module/zfs/ddt_stats.c \ - module/zfs/ddt_zap.c \ - module/zfs/dmu.c \ - module/zfs/dmu_diff.c \ - module/zfs/dmu_direct.c \ - module/zfs/dmu_object.c \ - module/zfs/dmu_objset.c \ - module/zfs/dmu_recv.c \ - module/zfs/dmu_redact.c \ - module/zfs/dmu_send.c \ - module/zfs/dmu_traverse.c \ - module/zfs/dmu_tx.c \ - module/zfs/dmu_zfetch.c \ - module/zfs/dnode.c \ - module/zfs/dnode_sync.c \ - module/zfs/dsl_bookmark.c \ - module/zfs/dsl_crypt.c \ - module/zfs/dsl_dataset.c \ - module/zfs/dsl_deadlist.c \ - module/zfs/dsl_deleg.c \ - module/zfs/dsl_destroy.c \ - module/zfs/dsl_dir.c \ - module/zfs/dsl_pool.c \ - module/zfs/dsl_prop.c \ - module/zfs/dsl_scan.c \ - module/zfs/dsl_synctask.c \ - module/zfs/dsl_userhold.c \ - module/zfs/edonr_zfs.c \ - module/zfs/fm.c \ - module/zfs/gzip.c \ - module/zfs/hkdf.c \ - module/zfs/lz4.c \ - module/zfs/lz4_zfs.c \ - module/zfs/lzjb.c \ - module/zfs/metaslab.c \ - module/zfs/mmp.c \ - module/zfs/multilist.c \ - module/zfs/objlist.c \ - module/zfs/pathname.c \ - module/zfs/range_tree.c \ - module/zfs/refcount.c \ - module/zfs/rrwlock.c \ - module/zfs/sa.c \ - module/zfs/sha2_zfs.c \ - module/zfs/skein_zfs.c \ - module/zfs/spa.c \ - module/zfs/spa_checkpoint.c \ - module/zfs/spa_config.c \ - module/zfs/spa_errlog.c \ - module/zfs/spa_history.c \ - module/zfs/spa_log_spacemap.c \ - module/zfs/spa_misc.c \ - module/zfs/spa_stats.c \ - module/zfs/space_map.c \ - module/zfs/space_reftree.c \ - module/zfs/txg.c \ - module/zfs/uberblock.c \ - module/zfs/unique.c \ - module/zfs/vdev.c \ - module/zfs/vdev_draid.c \ - module/zfs/vdev_draid_rand.c \ - module/zfs/vdev_file.c \ - module/zfs/vdev_indirect.c \ - module/zfs/vdev_indirect_births.c \ - module/zfs/vdev_indirect_mapping.c \ - module/zfs/vdev_initialize.c \ - module/zfs/vdev_label.c \ - module/zfs/vdev_mirror.c \ - module/zfs/vdev_missing.c \ - module/zfs/vdev_queue.c \ - module/zfs/vdev_raidz.c \ - module/zfs/vdev_raidz_math.c \ - module/zfs/vdev_raidz_math_aarch64_neon.c \ - module/zfs/vdev_raidz_math_aarch64_neonx2.c \ - module/zfs/vdev_raidz_math_avx2.c \ - module/zfs/vdev_raidz_math_avx512bw.c \ - module/zfs/vdev_raidz_math_avx512f.c \ - module/zfs/vdev_raidz_math_powerpc_altivec.c \ - module/zfs/vdev_raidz_math_scalar.c \ - module/zfs/vdev_raidz_math_sse2.c \ - module/zfs/vdev_raidz_math_ssse3.c \ - module/zfs/vdev_rebuild.c \ - module/zfs/vdev_removal.c \ - module/zfs/vdev_root.c \ - module/zfs/vdev_trim.c \ - module/zfs/zap.c \ - module/zfs/zap_leaf.c \ - module/zfs/zap_micro.c \ - module/zfs/zcp.c \ - module/zfs/zcp_get.c \ - module/zfs/zcp_global.c \ - module/zfs/zcp_iter.c \ - module/zfs/zcp_set.c \ - module/zfs/zcp_synctask.c \ - module/zfs/zfeature.c \ - module/zfs/zfs_byteswap.c \ - module/zfs/zfs_chksum.c \ - module/zfs/zfs_debug_common.c \ - module/zfs/zfs_crrd.c \ - module/zfs/zfs_fm.c \ - module/zfs/zfs_fuid.c \ - module/zfs/zfs_ratelimit.c \ - module/zfs/zfs_rlock.c \ - module/zfs/zfs_sa.c \ - module/zfs/zfs_znode.c \ - module/zfs/zil.c \ - module/zfs/zio.c \ - module/zfs/zio_checksum.c \ - module/zfs/zio_compress.c \ - module/zfs/zio_inject.c \ - module/zfs/zle.c \ - module/zfs/zrlock.c \ - module/zfs/zthr.c - -libzpool_la_LIBADD = \ - libicp.la \ - libunicode.la \ - libnvpair.la \ - libzstd.la \ - libzutil.la - -libzpool_la_LIBADD += $(LIBCLOCK_GETTIME) $(ZLIB_LIBS) -lm - -libzpool_la_LDFLAGS = -pthread - -if !ASAN_ENABLED -libzpool_la_LDFLAGS += -Wl,-z,defs -endif - -if BUILD_FREEBSD -libzpool_la_LIBADD += -lgeom -endif - -libzpool_la_LDFLAGS += -version-info 6:0:0 - -if TARGET_CPU_POWERPC -module/zfs/libzpool_la-vdev_raidz_math_powerpc_altivec.$(OBJEXT) : CFLAGS += -maltivec -module/zfs/libzpool_la-vdev_raidz_math_powerpc_altivec.l$(OBJEXT): CFLAGS += -maltivec -endif diff --git a/lib/libzpool/abd_os.c b/lib/libzpool/abd_os.c deleted file mode 100644 index 8bd7a64ab24a..000000000000 --- a/lib/libzpool/abd_os.c +++ /dev/null @@ -1,430 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2014 by Chunwei Chen. All rights reserved. - * Copyright (c) 2019 by Delphix. All rights reserved. - * Copyright (c) 2023, 2024, Klara Inc. - */ - -#include <sys/abd_impl.h> -#include <sys/param.h> -#include <sys/zio.h> -#include <sys/arc.h> -#include <sys/zfs_context.h> -#include <sys/zfs_znode.h> - -/* - * We're simulating scatter/gather with 4K allocations, since that's more like - * what a typical kernel does. - */ -#define ABD_PAGESIZE (4096) -#define ABD_PAGESHIFT (12) -#define ABD_PAGEMASK (ABD_PAGESIZE-1) - -/* - * See rationale in module/os/linux/zfs/abd_os.c, but in userspace this is - * mostly useful to get a mix of linear and scatter ABDs for testing. - */ -#define ABD_SCATTER_MIN_SIZE (512 * 3) - -abd_t *abd_zero_scatter = NULL; - -static uint_t -abd_iovcnt_for_bytes(size_t size) -{ - /* - * Each iovec points to a 4K page. There's no real reason to do this - * in userspace, but our whole point here is to make it feel a bit - * more like a real paged memory model. - */ - return (P2ROUNDUP(size, ABD_PAGESIZE) / ABD_PAGESIZE); -} - -abd_t * -abd_alloc_struct_impl(size_t size) -{ - /* - * Zero-sized means it will be used for a linear or gang abd, so just - * allocate the abd itself and return. - */ - if (size == 0) - return (umem_alloc(sizeof (abd_t), UMEM_NOFAIL)); - - /* - * Allocating for a scatter abd, so compute how many ABD_PAGESIZE - * iovecs we will need to hold this size. Append that allocation to the - * end. Note that struct abd_scatter has includes abd_iov[1], so we - * allocate one less iovec than we need. - * - * Note we're not allocating the pages proper, just the iovec pointers. - * That's down in abd_alloc_chunks. We _could_ do it here in a single - * allocation, but it's fiddly and harder to read for no real gain. - */ - uint_t n = abd_iovcnt_for_bytes(size); - abd_t *abd = umem_alloc(sizeof (abd_t) + (n-1) * sizeof (struct iovec), - UMEM_NOFAIL); - ABD_SCATTER(abd).abd_offset = 0; - ABD_SCATTER(abd).abd_iovcnt = n; - return (abd); -} - -void -abd_free_struct_impl(abd_t *abd) -{ - /* For scatter, compute the extra amount we need to free */ - uint_t iovcnt = - abd_is_linear(abd) || abd_is_gang(abd) ? - 0 : (ABD_SCATTER(abd).abd_iovcnt - 1); - umem_free(abd, sizeof (abd_t) + iovcnt * sizeof (struct iovec)); -} - -void -abd_alloc_chunks(abd_t *abd, size_t size) -{ - /* - * We've already allocated the iovec array; ensure that the wanted size - * actually matches, otherwise the caller has made a mistake somewhere. - */ - uint_t n = ABD_SCATTER(abd).abd_iovcnt; - ASSERT3U(n, ==, abd_iovcnt_for_bytes(size)); - - /* - * Allocate a ABD_PAGESIZE region for each iovec. - */ - struct iovec *iov = ABD_SCATTER(abd).abd_iov; - for (int i = 0; i < n; i++) { - iov[i].iov_base = - umem_alloc_aligned(ABD_PAGESIZE, ABD_PAGESIZE, UMEM_NOFAIL); - iov[i].iov_len = ABD_PAGESIZE; - } -} - -void -abd_free_chunks(abd_t *abd) -{ - uint_t n = ABD_SCATTER(abd).abd_iovcnt; - struct iovec *iov = ABD_SCATTER(abd).abd_iov; - for (int i = 0; i < n; i++) - umem_free_aligned(iov[i].iov_base, ABD_PAGESIZE); -} - -boolean_t -abd_size_alloc_linear(size_t size) -{ - return (size < ABD_SCATTER_MIN_SIZE); -} - -void -abd_update_scatter_stats(abd_t *abd, abd_stats_op_t op) -{ - ASSERT(op == ABDSTAT_INCR || op == ABDSTAT_DECR); - int waste = P2ROUNDUP(abd->abd_size, ABD_PAGESIZE) - abd->abd_size; - if (op == ABDSTAT_INCR) { - arc_space_consume(waste, ARC_SPACE_ABD_CHUNK_WASTE); - } else { - arc_space_return(waste, ARC_SPACE_ABD_CHUNK_WASTE); - } -} - -void -abd_update_linear_stats(abd_t *abd, abd_stats_op_t op) -{ - (void) abd; - (void) op; - ASSERT(op == ABDSTAT_INCR || op == ABDSTAT_DECR); -} - -void -abd_verify_scatter(abd_t *abd) -{ -#ifdef ZFS_DEBUG - /* - * scatter abds shall have: - * - at least one iovec - * - all iov_base point somewhere - * - all iov_len are ABD_PAGESIZE - * - offset set within the abd pages somewhere - */ - uint_t n = ABD_SCATTER(abd).abd_iovcnt; - ASSERT3U(n, >, 0); - - uint_t len = 0; - for (int i = 0; i < n; i++) { - ASSERT3P(ABD_SCATTER(abd).abd_iov[i].iov_base, !=, NULL); - ASSERT3U(ABD_SCATTER(abd).abd_iov[i].iov_len, ==, ABD_PAGESIZE); - len += ABD_PAGESIZE; - } - - ASSERT3U(ABD_SCATTER(abd).abd_offset, <, len); -#endif -} - -void -abd_init(void) -{ - /* - * Create the "zero" scatter abd. This is always the size of the - * largest possible block, but only actually has a single allocated - * page, which all iovecs in the abd point to. - */ - abd_zero_scatter = abd_alloc_struct(SPA_MAXBLOCKSIZE); - abd_zero_scatter->abd_flags |= ABD_FLAG_OWNER; - abd_zero_scatter->abd_size = SPA_MAXBLOCKSIZE; - - void *zero = - umem_alloc_aligned(ABD_PAGESIZE, ABD_PAGESIZE, UMEM_NOFAIL); - memset(zero, 0, ABD_PAGESIZE); - - uint_t n = abd_iovcnt_for_bytes(SPA_MAXBLOCKSIZE); - struct iovec *iov = ABD_SCATTER(abd_zero_scatter).abd_iov; - for (int i = 0; i < n; i++) { - iov[i].iov_base = zero; - iov[i].iov_len = ABD_PAGESIZE; - } -} - -void -abd_fini(void) -{ - umem_free_aligned( - ABD_SCATTER(abd_zero_scatter).abd_iov[0].iov_base, ABD_PAGESIZE); - abd_free_struct(abd_zero_scatter); - abd_zero_scatter = NULL; -} - -void -abd_free_linear_page(abd_t *abd) -{ - /* - * LINEAR_PAGE is specific to the Linux kernel; we never set this - * flag, so this will never be called. - */ - (void) abd; - PANIC("unreachable"); -} - -abd_t * -abd_alloc_for_io(size_t size, boolean_t is_metadata) -{ - return (abd_alloc(size, is_metadata)); -} - -abd_t * -abd_get_offset_scatter(abd_t *dabd, abd_t *sabd, size_t off, size_t size) -{ - - /* - * Create a new scatter dabd by borrowing data pages from sabd to cover - * off+size. - * - * sabd is an existing scatter abd with a set of iovecs, each covering - * an ABD_PAGESIZE (4K) allocation. It's "zero" is at abd_offset. - * - * [........][........][........][........] - * ^- sabd_offset - * - * We want to produce a new abd, referencing those allocations at the - * given offset. - * - * [........][........][........][........] - * ^- dabd_offset = sabd_offset + off - * ^- dabd_offset + size - * - * In this example, dabd needs three iovecs. The first iovec is offset - * 0, so the final dabd_offset is masked back into the first iovec. - * - * [........][........][........] - * ^- dabd_offset - */ - size_t soff = ABD_SCATTER(sabd).abd_offset + off; - size_t doff = soff & ABD_PAGEMASK; - size_t iovcnt = abd_iovcnt_for_bytes(doff + size); - - /* - * If the passed-in abd has enough allocated iovecs already, reuse it. - * Otherwise, make a new one. The caller will free the original if the - * one it gets back is not the same. - * - * Note that it's ok if we reuse an abd with more iovecs than we need. - * abd_size has the usable amount of data, and the abd does not own the - * pages referenced by the iovecs. At worst, they're holding dangling - * pointers that we'll never use anyway. - */ - if (dabd == NULL || ABD_SCATTER(dabd).abd_iovcnt < iovcnt) - dabd = abd_alloc_struct(iovcnt << ABD_PAGESHIFT); - - /* Set offset into first page in view */ - ABD_SCATTER(dabd).abd_offset = doff; - - /* Copy the wanted iovecs from the source to the dest */ - memcpy(&ABD_SCATTER(dabd).abd_iov[0], - &ABD_SCATTER(sabd).abd_iov[soff >> ABD_PAGESHIFT], - iovcnt * sizeof (struct iovec)); - - return (dabd); -} - -void -abd_iter_init(struct abd_iter *aiter, abd_t *abd) -{ - ASSERT(!abd_is_gang(abd)); - abd_verify(abd); - memset(aiter, 0, sizeof (struct abd_iter)); - aiter->iter_abd = abd; -} - -boolean_t -abd_iter_at_end(struct abd_iter *aiter) -{ - ASSERT3U(aiter->iter_pos, <=, aiter->iter_abd->abd_size); - return (aiter->iter_pos == aiter->iter_abd->abd_size); -} - -void -abd_iter_advance(struct abd_iter *aiter, size_t amount) -{ - ASSERT0P(aiter->iter_mapaddr); - ASSERT0(aiter->iter_mapsize); - - if (abd_iter_at_end(aiter)) - return; - - aiter->iter_pos += amount; - ASSERT3U(aiter->iter_pos, <=, aiter->iter_abd->abd_size); -} - -void -abd_iter_map(struct abd_iter *aiter) -{ - ASSERT0P(aiter->iter_mapaddr); - ASSERT0(aiter->iter_mapsize); - - if (abd_iter_at_end(aiter)) - return; - - if (abd_is_linear(aiter->iter_abd)) { - aiter->iter_mapaddr = - ABD_LINEAR_BUF(aiter->iter_abd) + aiter->iter_pos; - aiter->iter_mapsize = - aiter->iter_abd->abd_size - aiter->iter_pos; - return; - } - - /* - * For scatter, we index into the appropriate iovec, and return the - * smaller of the amount requested, or up to the end of the page. - */ - size_t poff = aiter->iter_pos + ABD_SCATTER(aiter->iter_abd).abd_offset; - - ASSERT3U(poff >> ABD_PAGESHIFT, <=, - ABD_SCATTER(aiter->iter_abd).abd_iovcnt); - struct iovec *iov = &ABD_SCATTER(aiter->iter_abd). - abd_iov[poff >> ABD_PAGESHIFT]; - - aiter->iter_mapsize = MIN(ABD_PAGESIZE - (poff & ABD_PAGEMASK), - aiter->iter_abd->abd_size - aiter->iter_pos); - ASSERT3U(aiter->iter_mapsize, <=, ABD_PAGESIZE); - - aiter->iter_mapaddr = iov->iov_base + (poff & ABD_PAGEMASK); -} - -void -abd_iter_unmap(struct abd_iter *aiter) -{ - if (abd_iter_at_end(aiter)) - return; - - ASSERT3P(aiter->iter_mapaddr, !=, NULL); - ASSERT3U(aiter->iter_mapsize, >, 0); - - aiter->iter_mapaddr = NULL; - aiter->iter_mapsize = 0; -} - -void -abd_cache_reap_now(void) -{ -} - -/* - * Borrow a raw buffer from an ABD without copying the contents of the ABD - * into the buffer. If the ABD is scattered, this will alloate a raw buffer - * whose contents are undefined. To copy over the existing data in the ABD, use - * abd_borrow_buf_copy() instead. - */ -void * -abd_borrow_buf(abd_t *abd, size_t n) -{ - void *buf; - abd_verify(abd); - ASSERT3U(abd->abd_size, >=, 0); - if (abd_is_linear(abd)) { - buf = abd_to_buf(abd); - } else { - buf = zio_buf_alloc(n); - } -#ifdef ZFS_DEBUG - (void) zfs_refcount_add_many(&abd->abd_children, n, buf); -#endif - return (buf); -} - -void * -abd_borrow_buf_copy(abd_t *abd, size_t n) -{ - void *buf = abd_borrow_buf(abd, n); - if (!abd_is_linear(abd)) { - abd_copy_to_buf(buf, abd, n); - } - return (buf); -} - -/* - * Return a borrowed raw buffer to an ABD. If the ABD is scattered, this will - * no change the contents of the ABD and will ASSERT that you didn't modify - * the buffer since it was borrowed. If you want any changes you made to buf to - * be copied back to abd, use abd_return_buf_copy() instead. - */ -void -abd_return_buf(abd_t *abd, void *buf, size_t n) -{ - abd_verify(abd); - ASSERT3U(abd->abd_size, >=, n); -#ifdef ZFS_DEBUG - (void) zfs_refcount_remove_many(&abd->abd_children, n, buf); -#endif - if (abd_is_linear(abd)) { - ASSERT3P(buf, ==, abd_to_buf(abd)); - } else { - ASSERT0(abd_cmp_buf(abd, buf, n)); - zio_buf_free(buf, n); - } -} - -void -abd_return_buf_copy(abd_t *abd, void *buf, size_t n) -{ - if (!abd_is_linear(abd)) { - abd_copy_from_buf(abd, buf, n); - } - abd_return_buf(abd, buf, n); -} diff --git a/lib/libzpool/arc_os.c b/lib/libzpool/arc_os.c deleted file mode 100644 index 6ad1a2bcda6e..000000000000 --- a/lib/libzpool/arc_os.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, Joyent, Inc. - * Copyright (c) 2011, 2019 by Delphix. All rights reserved. - * Copyright (c) 2014 by Saso Kiselkov. All rights reserved. - * Copyright 2017 Nexenta Systems, Inc. All rights reserved. - */ - -#include <sys/zfs_context.h> -#include <sys/arc_impl.h> - -/* - * Return a default max arc size based on the amount of physical memory. - * This may be overridden by tuning the zfs_arc_max module parameter. - */ -uint64_t -arc_default_max(uint64_t min, uint64_t allmem) -{ - uint64_t size; - - if (allmem >= 1 << 30) - size = allmem - (1 << 30); - else - size = min; - return (MAX(allmem * 5 / 8, size)); -} - -int64_t -arc_available_memory(void) -{ - int64_t lowest = INT64_MAX; - - /* Every 100 calls, free a small amount */ - if (random_in_range(100) == 0) - lowest = -1024; - - return (lowest); -} - -int -arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg) -{ - (void) spa, (void) reserve, (void) txg; - return (0); -} - -uint64_t -arc_all_memory(void) -{ - return (ptob(physmem) / 2); -} - -uint64_t -arc_free_memory(void) -{ - return (random_in_range(arc_all_memory() * 20 / 100)); -} - -void -arc_register_hotplug(void) -{ -} - -void -arc_unregister_hotplug(void) -{ -} diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c deleted file mode 100644 index 8ed374627264..000000000000 --- a/lib/libzpool/kernel.c +++ /dev/null @@ -1,1540 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 by Delphix. All rights reserved. - * Copyright (c) 2016 Actifio, Inc. All rights reserved. - */ - -#include <assert.h> -#include <fcntl.h> -#include <libgen.h> -#include <poll.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <libzutil.h> -#include <sys/crypto/icp.h> -#include <sys/processor.h> -#include <sys/rrwlock.h> -#include <sys/spa.h> -#include <sys/spa_impl.h> -#include <sys/stat.h> -#include <sys/systeminfo.h> -#include <sys/time.h> -#include <sys/utsname.h> -#include <sys/zfs_context.h> -#include <sys/zfs_onexit.h> -#include <sys/zfs_vfsops.h> -#include <sys/zstd/zstd.h> -#include <sys/zvol.h> -#include <zfs_fletcher.h> -#include <zlib.h> - -/* - * Emulation of kernel services in userland. - */ - -uint64_t physmem; -uint32_t hostid; -struct utsname hw_utsname; - -/* If set, all blocks read will be copied to the specified directory. */ -char *vn_dumpdir = NULL; - -/* this only exists to have its address taken */ -struct proc p0; - -/* - * ========================================================================= - * threads - * ========================================================================= - * - * TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While - * TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for - * the expected stack depth while small enough to avoid exhausting address - * space with high thread counts. - */ -#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768) -#define TS_STACK_MAX (256 * 1024) - -struct zk_thread_wrapper { - void (*func)(void *); - void *arg; -}; - -static void * -zk_thread_wrapper(void *arg) -{ - struct zk_thread_wrapper ztw; - memcpy(&ztw, arg, sizeof (ztw)); - free(arg); - ztw.func(ztw.arg); - return (NULL); -} - -kthread_t * -zk_thread_create(const char *name, void (*func)(void *), void *arg, - size_t stksize, int state) -{ - pthread_attr_t attr; - pthread_t tid; - char *stkstr; - struct zk_thread_wrapper *ztw; - int detachstate = PTHREAD_CREATE_DETACHED; - - VERIFY0(pthread_attr_init(&attr)); - - if (state & TS_JOINABLE) - detachstate = PTHREAD_CREATE_JOINABLE; - - VERIFY0(pthread_attr_setdetachstate(&attr, detachstate)); - - /* - * We allow the default stack size in user space to be specified by - * setting the ZFS_STACK_SIZE environment variable. This allows us - * the convenience of observing and debugging stack overruns in - * user space. Explicitly specified stack sizes will be honored. - * The usage of ZFS_STACK_SIZE is discussed further in the - * ENVIRONMENT VARIABLES sections of the ztest(1) man page. - */ - if (stksize == 0) { - stkstr = getenv("ZFS_STACK_SIZE"); - - if (stkstr == NULL) - stksize = TS_STACK_MAX; - else - stksize = MAX(atoi(stkstr), TS_STACK_MIN); - } - - VERIFY3S(stksize, >, 0); - stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE); - - /* - * If this ever fails, it may be because the stack size is not a - * multiple of system page size. - */ - VERIFY0(pthread_attr_setstacksize(&attr, stksize)); - VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE)); - - VERIFY(ztw = malloc(sizeof (*ztw))); - ztw->func = func; - ztw->arg = arg; - VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw)); - VERIFY0(pthread_attr_destroy(&attr)); - - pthread_setname_np(tid, name); - - return ((void *)(uintptr_t)tid); -} - -/* - * ========================================================================= - * kstats - * ========================================================================= - */ -kstat_t * -kstat_create(const char *module, int instance, const char *name, - const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag) -{ - (void) module, (void) instance, (void) name, (void) class, (void) type, - (void) ndata, (void) ks_flag; - return (NULL); -} - -void -kstat_install(kstat_t *ksp) -{ - (void) ksp; -} - -void -kstat_delete(kstat_t *ksp) -{ - (void) ksp; -} - -void -kstat_set_raw_ops(kstat_t *ksp, - int (*headers)(char *buf, size_t size), - int (*data)(char *buf, size_t size, void *data), - void *(*addr)(kstat_t *ksp, loff_t index)) -{ - (void) ksp, (void) headers, (void) data, (void) addr; -} - -/* - * ========================================================================= - * mutexes - * ========================================================================= - */ - -void -mutex_init(kmutex_t *mp, char *name, int type, void *cookie) -{ - (void) name, (void) type, (void) cookie; - VERIFY0(pthread_mutex_init(&mp->m_lock, NULL)); - memset(&mp->m_owner, 0, sizeof (pthread_t)); -} - -void -mutex_destroy(kmutex_t *mp) -{ - VERIFY0(pthread_mutex_destroy(&mp->m_lock)); -} - -void -mutex_enter(kmutex_t *mp) -{ - VERIFY0(pthread_mutex_lock(&mp->m_lock)); - mp->m_owner = pthread_self(); -} - -int -mutex_enter_check_return(kmutex_t *mp) -{ - int error = pthread_mutex_lock(&mp->m_lock); - if (error == 0) - mp->m_owner = pthread_self(); - return (error); -} - -int -mutex_tryenter(kmutex_t *mp) -{ - int error = pthread_mutex_trylock(&mp->m_lock); - if (error == 0) { - mp->m_owner = pthread_self(); - return (1); - } else { - VERIFY3S(error, ==, EBUSY); - return (0); - } -} - -void -mutex_exit(kmutex_t *mp) -{ - memset(&mp->m_owner, 0, sizeof (pthread_t)); - VERIFY0(pthread_mutex_unlock(&mp->m_lock)); -} - -/* - * ========================================================================= - * rwlocks - * ========================================================================= - */ - -void -rw_init(krwlock_t *rwlp, char *name, int type, void *arg) -{ - (void) name, (void) type, (void) arg; - VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL)); - rwlp->rw_readers = 0; - rwlp->rw_owner = 0; -} - -void -rw_destroy(krwlock_t *rwlp) -{ - VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock)); -} - -void -rw_enter(krwlock_t *rwlp, krw_t rw) -{ - if (rw == RW_READER) { - VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock)); - atomic_inc_uint(&rwlp->rw_readers); - } else { - VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock)); - rwlp->rw_owner = pthread_self(); - } -} - -void -rw_exit(krwlock_t *rwlp) -{ - if (RW_READ_HELD(rwlp)) - atomic_dec_uint(&rwlp->rw_readers); - else - rwlp->rw_owner = 0; - - VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock)); -} - -int -rw_tryenter(krwlock_t *rwlp, krw_t rw) -{ - int error; - - if (rw == RW_READER) - error = pthread_rwlock_tryrdlock(&rwlp->rw_lock); - else - error = pthread_rwlock_trywrlock(&rwlp->rw_lock); - - if (error == 0) { - if (rw == RW_READER) - atomic_inc_uint(&rwlp->rw_readers); - else - rwlp->rw_owner = pthread_self(); - - return (1); - } - - VERIFY3S(error, ==, EBUSY); - - return (0); -} - -uint32_t -zone_get_hostid(void *zonep) -{ - /* - * We're emulating the system's hostid in userland. - */ - (void) zonep; - return (hostid); -} - -int -rw_tryupgrade(krwlock_t *rwlp) -{ - (void) rwlp; - return (0); -} - -/* - * ========================================================================= - * condition variables - * ========================================================================= - */ - -void -cv_init(kcondvar_t *cv, char *name, int type, void *arg) -{ - (void) name, (void) type, (void) arg; - VERIFY0(pthread_cond_init(cv, NULL)); -} - -void -cv_destroy(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_destroy(cv)); -} - -void -cv_wait(kcondvar_t *cv, kmutex_t *mp) -{ - memset(&mp->m_owner, 0, sizeof (pthread_t)); - VERIFY0(pthread_cond_wait(cv, &mp->m_lock)); - mp->m_owner = pthread_self(); -} - -int -cv_wait_sig(kcondvar_t *cv, kmutex_t *mp) -{ - cv_wait(cv, mp); - return (1); -} - -int -cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) -{ - int error; - struct timeval tv; - struct timespec ts; - clock_t delta; - - delta = abstime - ddi_get_lbolt(); - if (delta <= 0) - return (-1); - - VERIFY0(gettimeofday(&tv, NULL)); - - ts.tv_sec = tv.tv_sec + delta / hz; - ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz); - if (ts.tv_nsec >= NANOSEC) { - ts.tv_sec++; - ts.tv_nsec -= NANOSEC; - } - - memset(&mp->m_owner, 0, sizeof (pthread_t)); - error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); - mp->m_owner = pthread_self(); - - if (error == ETIMEDOUT) - return (-1); - - VERIFY0(error); - - return (1); -} - -int -cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res, - int flag) -{ - (void) res; - int error; - struct timeval tv; - struct timespec ts; - hrtime_t delta; - - ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE); - - delta = tim; - if (flag & CALLOUT_FLAG_ABSOLUTE) - delta -= gethrtime(); - - if (delta <= 0) - return (-1); - - VERIFY0(gettimeofday(&tv, NULL)); - - ts.tv_sec = tv.tv_sec + delta / NANOSEC; - ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC); - if (ts.tv_nsec >= NANOSEC) { - ts.tv_sec++; - ts.tv_nsec -= NANOSEC; - } - - memset(&mp->m_owner, 0, sizeof (pthread_t)); - error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); - mp->m_owner = pthread_self(); - - if (error == ETIMEDOUT) - return (-1); - - VERIFY0(error); - - return (1); -} - -void -cv_signal(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_signal(cv)); -} - -void -cv_broadcast(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_broadcast(cv)); -} - -/* - * ========================================================================= - * procfs list - * ========================================================================= - */ - -void -seq_printf(struct seq_file *m, const char *fmt, ...) -{ - (void) m, (void) fmt; -} - -void -procfs_list_install(const char *module, - const char *submodule, - const char *name, - mode_t mode, - procfs_list_t *procfs_list, - int (*show)(struct seq_file *f, void *p), - int (*show_header)(struct seq_file *f), - int (*clear)(procfs_list_t *procfs_list), - size_t procfs_list_node_off) -{ - (void) module, (void) submodule, (void) name, (void) mode, (void) show, - (void) show_header, (void) clear; - mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL); - list_create(&procfs_list->pl_list, - procfs_list_node_off + sizeof (procfs_list_node_t), - procfs_list_node_off + offsetof(procfs_list_node_t, pln_link)); - procfs_list->pl_next_id = 1; - procfs_list->pl_node_offset = procfs_list_node_off; -} - -void -procfs_list_uninstall(procfs_list_t *procfs_list) -{ - (void) procfs_list; -} - -void -procfs_list_destroy(procfs_list_t *procfs_list) -{ - ASSERT(list_is_empty(&procfs_list->pl_list)); - list_destroy(&procfs_list->pl_list); - mutex_destroy(&procfs_list->pl_lock); -} - -#define NODE_ID(procfs_list, obj) \ - (((procfs_list_node_t *)(((char *)obj) + \ - (procfs_list)->pl_node_offset))->pln_id) - -void -procfs_list_add(procfs_list_t *procfs_list, void *p) -{ - ASSERT(MUTEX_HELD(&procfs_list->pl_lock)); - NODE_ID(procfs_list, p) = procfs_list->pl_next_id++; - list_insert_tail(&procfs_list->pl_list, p); -} - -/* - * ========================================================================= - * vnode operations - * ========================================================================= - */ - -/* - * ========================================================================= - * Figure out which debugging statements to print - * ========================================================================= - */ - -static char *dprintf_string; -static int dprintf_print_all; - -int -dprintf_find_string(const char *string) -{ - char *tmp_str = dprintf_string; - int len = strlen(string); - - /* - * Find out if this is a string we want to print. - * String format: file1.c,function_name1,file2.c,file3.c - */ - - while (tmp_str != NULL) { - if (strncmp(tmp_str, string, len) == 0 && - (tmp_str[len] == ',' || tmp_str[len] == '\0')) - return (1); - tmp_str = strchr(tmp_str, ','); - if (tmp_str != NULL) - tmp_str++; /* Get rid of , */ - } - return (0); -} - -void -dprintf_setup(int *argc, char **argv) -{ - int i, j; - - /* - * Debugging can be specified two ways: by setting the - * environment variable ZFS_DEBUG, or by including a - * "debug=..." argument on the command line. The command - * line setting overrides the environment variable. - */ - - for (i = 1; i < *argc; i++) { - int len = strlen("debug="); - /* First look for a command line argument */ - if (strncmp("debug=", argv[i], len) == 0) { - dprintf_string = argv[i] + len; - /* Remove from args */ - for (j = i; j < *argc; j++) - argv[j] = argv[j+1]; - argv[j] = NULL; - (*argc)--; - } - } - - if (dprintf_string == NULL) { - /* Look for ZFS_DEBUG environment variable */ - dprintf_string = getenv("ZFS_DEBUG"); - } - - /* - * Are we just turning on all debugging? - */ - if (dprintf_find_string("on")) - dprintf_print_all = 1; - - if (dprintf_string != NULL) - zfs_flags |= ZFS_DEBUG_DPRINTF; -} - -/* - * ========================================================================= - * debug printfs - * ========================================================================= - */ -void -__dprintf(boolean_t dprint, const char *file, const char *func, - int line, const char *fmt, ...) -{ - /* Get rid of annoying "../common/" prefix to filename. */ - const char *newfile = zfs_basename(file); - - va_list adx; - if (dprint) { - /* dprintf messages are printed immediately */ - - if (!dprintf_print_all && - !dprintf_find_string(newfile) && - !dprintf_find_string(func)) - return; - - /* Print out just the function name if requested */ - flockfile(stdout); - if (dprintf_find_string("pid")) - (void) printf("%d ", getpid()); - if (dprintf_find_string("tid")) - (void) printf("%ju ", - (uintmax_t)(uintptr_t)pthread_self()); - if (dprintf_find_string("cpu")) - (void) printf("%u ", getcpuid()); - if (dprintf_find_string("time")) - (void) printf("%llu ", gethrtime()); - if (dprintf_find_string("long")) - (void) printf("%s, line %d: ", newfile, line); - (void) printf("dprintf: %s: ", func); - va_start(adx, fmt); - (void) vprintf(fmt, adx); - va_end(adx); - funlockfile(stdout); - } else { - /* zfs_dbgmsg is logged for dumping later */ - size_t size; - char *buf; - int i; - - size = 1024; - buf = umem_alloc(size, UMEM_NOFAIL); - i = snprintf(buf, size, "%s:%d:%s(): ", newfile, line, func); - - if (i < size) { - va_start(adx, fmt); - (void) vsnprintf(buf + i, size - i, fmt, adx); - va_end(adx); - } - - __zfs_dbgmsg(buf); - - umem_free(buf, size); - } -} - -/* - * ========================================================================= - * cmn_err() and panic() - * ========================================================================= - */ -static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" }; -static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" }; - -__attribute__((noreturn)) void -vpanic(const char *fmt, va_list adx) -{ - (void) fprintf(stderr, "error: "); - (void) vfprintf(stderr, fmt, adx); - (void) fprintf(stderr, "\n"); - - abort(); /* think of it as a "user-level crash dump" */ -} - -__attribute__((noreturn)) void -panic(const char *fmt, ...) -{ - va_list adx; - - va_start(adx, fmt); - vpanic(fmt, adx); - va_end(adx); -} - -void -vcmn_err(int ce, const char *fmt, va_list adx) -{ - if (ce == CE_PANIC) - vpanic(fmt, adx); - if (ce != CE_NOTE) { /* suppress noise in userland stress testing */ - (void) fprintf(stderr, "%s", ce_prefix[ce]); - (void) vfprintf(stderr, fmt, adx); - (void) fprintf(stderr, "%s", ce_suffix[ce]); - } -} - -void -cmn_err(int ce, const char *fmt, ...) -{ - va_list adx; - - va_start(adx, fmt); - vcmn_err(ce, fmt, adx); - va_end(adx); -} - -/* - * ========================================================================= - * misc routines - * ========================================================================= - */ - -void -delay(clock_t ticks) -{ - (void) poll(0, 0, ticks * (1000 / hz)); -} - -/* - * Find highest one bit set. - * Returns bit number + 1 of highest bit that is set, otherwise returns 0. - * The __builtin_clzll() function is supported by both GCC and Clang. - */ -int -highbit64(uint64_t i) -{ - if (i == 0) - return (0); - - return (NBBY * sizeof (uint64_t) - __builtin_clzll(i)); -} - -/* - * Find lowest one bit set. - * Returns bit number + 1 of lowest bit that is set, otherwise returns 0. - * The __builtin_ffsll() function is supported by both GCC and Clang. - */ -int -lowbit64(uint64_t i) -{ - if (i == 0) - return (0); - - return (__builtin_ffsll(i)); -} - -const char *random_path = "/dev/random"; -const char *urandom_path = "/dev/urandom"; -static int random_fd = -1, urandom_fd = -1; - -void -random_init(void) -{ - VERIFY((random_fd = open(random_path, O_RDONLY | O_CLOEXEC)) != -1); - VERIFY((urandom_fd = open(urandom_path, O_RDONLY | O_CLOEXEC)) != -1); -} - -void -random_fini(void) -{ - close(random_fd); - close(urandom_fd); - - random_fd = -1; - urandom_fd = -1; -} - -static int -random_get_bytes_common(uint8_t *ptr, size_t len, int fd) -{ - size_t resid = len; - ssize_t bytes; - - ASSERT(fd != -1); - - while (resid != 0) { - bytes = read(fd, ptr, resid); - ASSERT3S(bytes, >=, 0); - ptr += bytes; - resid -= bytes; - } - - return (0); -} - -int -random_get_bytes(uint8_t *ptr, size_t len) -{ - return (random_get_bytes_common(ptr, len, random_fd)); -} - -int -random_get_pseudo_bytes(uint8_t *ptr, size_t len) -{ - return (random_get_bytes_common(ptr, len, urandom_fd)); -} - -int -ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) -{ - errno = 0; - *result = strtoull(str, nptr, base); - if (*result == 0) - return (errno); - return (0); -} - -utsname_t * -utsname(void) -{ - return (&hw_utsname); -} - -/* - * ========================================================================= - * kernel emulation setup & teardown - * ========================================================================= - */ -static int -umem_out_of_memory(void) -{ - char errmsg[] = "out of memory -- generating core dump\n"; - - (void) fprintf(stderr, "%s", errmsg); - abort(); - return (0); -} - -static void -spa_config_load(void) -{ - void *buf = NULL; - nvlist_t *nvlist, *child; - nvpair_t *nvpair; - char *pathname; - zfs_file_t *fp; - zfs_file_attr_t zfa; - uint64_t fsize; - int err; - - /* - * Open the configuration file. - */ - pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); - - (void) snprintf(pathname, MAXPATHLEN, "%s", spa_config_path); - - err = zfs_file_open(pathname, O_RDONLY, 0, &fp); - if (err) - err = zfs_file_open(ZPOOL_CACHE_BOOT, O_RDONLY, 0, &fp); - - kmem_free(pathname, MAXPATHLEN); - - if (err) - return; - - if (zfs_file_getattr(fp, &zfa)) - goto out; - - fsize = zfa.zfa_size; - buf = kmem_alloc(fsize, KM_SLEEP); - - /* - * Read the nvlist from the file. - */ - if (zfs_file_read(fp, buf, fsize, NULL) < 0) - goto out; - - /* - * Unpack the nvlist. - */ - if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0) - goto out; - - /* - * Iterate over all elements in the nvlist, creating a new spa_t for - * each one with the specified configuration. - */ - mutex_enter(&spa_namespace_lock); - nvpair = NULL; - while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) { - if (nvpair_type(nvpair) != DATA_TYPE_NVLIST) - continue; - - child = fnvpair_value_nvlist(nvpair); - - if (spa_lookup(nvpair_name(nvpair)) != NULL) - continue; - (void) spa_add(nvpair_name(nvpair), child, NULL); - } - mutex_exit(&spa_namespace_lock); - - nvlist_free(nvlist); - -out: - if (buf != NULL) - kmem_free(buf, fsize); - - zfs_file_close(fp); -} - -void -kernel_init(int mode) -{ - extern uint_t rrw_tsd_key; - - umem_nofail_callback(umem_out_of_memory); - - physmem = sysconf(_SC_PHYS_PAGES); - - dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, - (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); - - hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; - - random_init(); - - VERIFY0(uname(&hw_utsname)); - - system_taskq_init(); - icp_init(); - - zstd_init(); - - spa_init((spa_mode_t)mode); - spa_config_load(); - - fletcher_4_init(); - - tsd_create(&rrw_tsd_key, rrw_tsd_destroy); -} - -void -kernel_fini(void) -{ - fletcher_4_fini(); - spa_fini(); - - zstd_fini(); - - icp_fini(); - system_taskq_fini(); - - random_fini(); -} - -uid_t -crgetuid(cred_t *cr) -{ - (void) cr; - return (0); -} - -uid_t -crgetruid(cred_t *cr) -{ - (void) cr; - return (0); -} - -gid_t -crgetgid(cred_t *cr) -{ - (void) cr; - return (0); -} - -int -crgetngroups(cred_t *cr) -{ - (void) cr; - return (0); -} - -gid_t * -crgetgroups(cred_t *cr) -{ - (void) cr; - return (NULL); -} - -int -zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) -{ - (void) from, (void) to, (void) cr; - return (0); -} - -int -zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -secpolicy_zfs(const cred_t *cr) -{ - (void) cr; - return (0); -} - -ksiddomain_t * -ksid_lookupdomain(const char *dom) -{ - ksiddomain_t *kd; - - kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL); - kd->kd_name = spa_strdup(dom); - return (kd); -} - -void -ksiddomain_rele(ksiddomain_t *ksid) -{ - spa_strfree(ksid->kd_name); - umem_free(ksid, sizeof (ksiddomain_t)); -} - -char * -kmem_vasprintf(const char *fmt, va_list adx) -{ - char *buf = NULL; - va_list adx_copy; - - va_copy(adx_copy, adx); - VERIFY(vasprintf(&buf, fmt, adx_copy) != -1); - va_end(adx_copy); - - return (buf); -} - -char * -kmem_asprintf(const char *fmt, ...) -{ - char *buf = NULL; - va_list adx; - - va_start(adx, fmt); - VERIFY(vasprintf(&buf, fmt, adx) != -1); - va_end(adx); - - return (buf); -} - -/* - * kmem_scnprintf() will return the number of characters that it would have - * printed whenever it is limited by value of the size variable, rather than - * the number of characters that it did print. This can cause misbehavior on - * subsequent uses of the return value, so we define a safe version that will - * return the number of characters actually printed, minus the NULL format - * character. Subsequent use of this by the safe string functions is safe - * whether it is snprintf(), strlcat() or strlcpy(). - */ -int -kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...) -{ - int n; - va_list ap; - - /* Make the 0 case a no-op so that we do not return -1 */ - if (size == 0) - return (0); - - va_start(ap, fmt); - n = vsnprintf(str, size, fmt, ap); - va_end(ap); - - if (n >= size) - n = size - 1; - - return (n); -} - -zfs_file_t * -zfs_onexit_fd_hold(int fd, minor_t *minorp) -{ - (void) fd; - *minorp = 0; - return (NULL); -} - -void -zfs_onexit_fd_rele(zfs_file_t *fp) -{ - (void) fp; -} - -int -zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, - uintptr_t *action_handle) -{ - (void) minor, (void) func, (void) data, (void) action_handle; - return (0); -} - -fstrans_cookie_t -spl_fstrans_mark(void) -{ - return ((fstrans_cookie_t)0); -} - -void -spl_fstrans_unmark(fstrans_cookie_t cookie) -{ - (void) cookie; -} - -int -kmem_cache_reap_active(void) -{ - return (0); -} - -void -zvol_create_minors(const char *name) -{ - (void) name; -} - -void -zvol_remove_minors(spa_t *spa, const char *name, boolean_t async) -{ - (void) spa, (void) name, (void) async; -} - -void -zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname, - boolean_t async) -{ - (void) spa, (void) oldname, (void) newname, (void) async; -} - -/* - * Open file - * - * path - fully qualified path to file - * flags - file attributes O_READ / O_WRITE / O_EXCL - * fpp - pointer to return file pointer - * - * Returns 0 on success underlying error on failure. - */ -int -zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp) -{ - int fd; - int dump_fd; - int err; - int old_umask = 0; - zfs_file_t *fp; - struct stat64 st; - - if (!(flags & O_CREAT) && stat64(path, &st) == -1) - return (errno); - - if (!(flags & O_CREAT) && S_ISBLK(st.st_mode)) - flags |= O_DIRECT; - - if (flags & O_CREAT) - old_umask = umask(0); - - fd = open64(path, flags, mode); - if (fd == -1) - return (errno); - - if (flags & O_CREAT) - (void) umask(old_umask); - - if (vn_dumpdir != NULL) { - char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL); - const char *inpath = zfs_basename(path); - - (void) snprintf(dumppath, MAXPATHLEN, - "%s/%s", vn_dumpdir, inpath); - dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666); - umem_free(dumppath, MAXPATHLEN); - if (dump_fd == -1) { - err = errno; - close(fd); - return (err); - } - } else { - dump_fd = -1; - } - - (void) fcntl(fd, F_SETFD, FD_CLOEXEC); - - fp = umem_zalloc(sizeof (zfs_file_t), UMEM_NOFAIL); - fp->f_fd = fd; - fp->f_dump_fd = dump_fd; - *fpp = fp; - - return (0); -} - -void -zfs_file_close(zfs_file_t *fp) -{ - close(fp->f_fd); - if (fp->f_dump_fd != -1) - close(fp->f_dump_fd); - - umem_free(fp, sizeof (zfs_file_t)); -} - -/* - * Stateful write - use os internal file pointer to determine where to - * write and update on successful completion. - * - * fp - pointer to file (pipe, socket, etc) to write to - * buf - buffer to write - * count - # of bytes to write - * resid - pointer to count of unwritten bytes (if short write) - * - * Returns 0 on success errno on failure. - */ -int -zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid) -{ - ssize_t rc; - - rc = write(fp->f_fd, buf, count); - if (rc < 0) - return (errno); - - if (resid) { - *resid = count - rc; - } else if (rc != count) { - return (EIO); - } - - return (0); -} - -/* - * Stateless write - os internal file pointer is not updated. - * - * fp - pointer to file (pipe, socket, etc) to write to - * buf - buffer to write - * count - # of bytes to write - * off - file offset to write to (only valid for seekable types) - * resid - pointer to count of unwritten bytes - * - * Returns 0 on success errno on failure. - */ -int -zfs_file_pwrite(zfs_file_t *fp, const void *buf, - size_t count, loff_t pos, uint8_t ashift, ssize_t *resid) -{ - ssize_t rc, split, done; - int sectors; - - /* - * To simulate partial disk writes, we split writes into two - * system calls so that the process can be killed in between. - * This is used by ztest to simulate realistic failure modes. - */ - sectors = count >> ashift; - split = (sectors > 0 ? rand() % sectors : 0) << ashift; - rc = pwrite64(fp->f_fd, buf, split, pos); - if (rc != -1) { - done = rc; - rc = pwrite64(fp->f_fd, (char *)buf + split, - count - split, pos + split); - } -#ifdef __linux__ - if (rc == -1 && errno == EINVAL) { - /* - * Under Linux, this most likely means an alignment issue - * (memory or disk) due to O_DIRECT, so we abort() in order - * to catch the offender. - */ - abort(); - } -#endif - - if (rc < 0) - return (errno); - - done += rc; - - if (resid) { - *resid = count - done; - } else if (done != count) { - return (EIO); - } - - return (0); -} - -/* - * Stateful read - use os internal file pointer to determine where to - * read and update on successful completion. - * - * fp - pointer to file (pipe, socket, etc) to read from - * buf - buffer to write - * count - # of bytes to read - * resid - pointer to count of unread bytes (if short read) - * - * Returns 0 on success errno on failure. - */ -int -zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid) -{ - int rc; - - rc = read(fp->f_fd, buf, count); - if (rc < 0) - return (errno); - - if (resid) { - *resid = count - rc; - } else if (rc != count) { - return (EIO); - } - - return (0); -} - -/* - * Stateless read - os internal file pointer is not updated. - * - * fp - pointer to file (pipe, socket, etc) to read from - * buf - buffer to write - * count - # of bytes to write - * off - file offset to read from (only valid for seekable types) - * resid - pointer to count of unwritten bytes (if short write) - * - * Returns 0 on success errno on failure. - */ -int -zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off, - ssize_t *resid) -{ - ssize_t rc; - - rc = pread64(fp->f_fd, buf, count, off); - if (rc < 0) { -#ifdef __linux__ - /* - * Under Linux, this most likely means an alignment issue - * (memory or disk) due to O_DIRECT, so we abort() in order to - * catch the offender. - */ - if (errno == EINVAL) - abort(); -#endif - return (errno); - } - - if (fp->f_dump_fd != -1) { - int status; - - status = pwrite64(fp->f_dump_fd, buf, rc, off); - ASSERT(status != -1); - } - - if (resid) { - *resid = count - rc; - } else if (rc != count) { - return (EIO); - } - - return (0); -} - -/* - * lseek - set / get file pointer - * - * fp - pointer to file (pipe, socket, etc) to read from - * offp - value to seek to, returns current value plus passed offset - * whence - see man pages for standard lseek whence values - * - * Returns 0 on success errno on failure (ESPIPE for non seekable types) - */ -int -zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence) -{ - loff_t rc; - - rc = lseek(fp->f_fd, *offp, whence); - if (rc < 0) - return (errno); - - *offp = rc; - - return (0); -} - -/* - * Get file attributes - * - * filp - file pointer - * zfattr - pointer to file attr structure - * - * Currently only used for fetching size and file mode - * - * Returns 0 on success or error code of underlying getattr call on failure. - */ -int -zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr) -{ - struct stat64 st; - - if (fstat64_blk(fp->f_fd, &st) == -1) - return (errno); - - zfattr->zfa_size = st.st_size; - zfattr->zfa_mode = st.st_mode; - - return (0); -} - -/* - * Sync file to disk - * - * filp - file pointer - * flags - O_SYNC and or O_DSYNC - * - * Returns 0 on success or error code of underlying sync call on failure. - */ -int -zfs_file_fsync(zfs_file_t *fp, int flags) -{ - (void) flags; - - if (fsync(fp->f_fd) < 0) - return (errno); - - return (0); -} - -/* - * deallocate - zero and/or deallocate file storage - * - * fp - file pointer - * offset - offset to start zeroing or deallocating - * len - length to zero or deallocate - */ -int -zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len) -{ - int rc; -#if defined(__linux__) - rc = fallocate(fp->f_fd, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len); -#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029) - struct spacectl_range rqsr = { - .r_offset = offset, - .r_len = len, - }; - rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr); -#else - (void) fp, (void) offset, (void) len; - rc = EOPNOTSUPP; -#endif - if (rc) - return (SET_ERROR(rc)); - return (0); -} - -/* - * Request current file pointer offset - * - * fp - pointer to file - * - * Returns current file offset. - */ -loff_t -zfs_file_off(zfs_file_t *fp) -{ - return (lseek(fp->f_fd, SEEK_CUR, 0)); -} - -/* - * unlink file - * - * path - fully qualified file path - * - * Returns 0 on success. - * - * OPTIONAL - */ -int -zfs_file_unlink(const char *path) -{ - return (remove(path)); -} - -/* - * Get reference to file pointer - * - * fd - input file descriptor - * - * Returns pointer to file struct or NULL. - * Unsupported in user space. - */ -zfs_file_t * -zfs_file_get(int fd) -{ - (void) fd; - abort(); - return (NULL); -} -/* - * Drop reference to file pointer - * - * fp - pointer to file struct - * - * Unsupported in user space. - */ -void -zfs_file_put(zfs_file_t *fp) -{ - abort(); - (void) fp; -} - -void -zfsvfs_update_fromname(const char *oldname, const char *newname) -{ - (void) oldname, (void) newname; -} - -void -spa_import_os(spa_t *spa) -{ - (void) spa; -} - -void -spa_export_os(spa_t *spa) -{ - (void) spa; -} - -void -spa_activate_os(spa_t *spa) -{ - (void) spa; -} - -void -spa_deactivate_os(spa_t *spa) -{ - (void) spa; -} diff --git a/lib/libzpool/taskq.c b/lib/libzpool/taskq.c deleted file mode 100644 index 0457de21fa18..000000000000 --- a/lib/libzpool/taskq.c +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. - * Copyright (c) 2014 by Delphix. All rights reserved. - */ - -#include <sys/zfs_context.h> - -int taskq_now; -taskq_t *system_taskq; -taskq_t *system_delay_taskq; - -static pthread_key_t taskq_tsd; - -#define TASKQ_ACTIVE 0x00010000 - -static taskq_ent_t * -task_alloc(taskq_t *tq, int tqflags) -{ - taskq_ent_t *t; - int rv; - -again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) { - ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC)); - tq->tq_freelist = t->tqent_next; - } else { - if (tq->tq_nalloc >= tq->tq_maxalloc) { - if (!(tqflags & KM_SLEEP)) - return (NULL); - - /* - * We don't want to exceed tq_maxalloc, but we can't - * wait for other tasks to complete (and thus free up - * task structures) without risking deadlock with - * the caller. So, we just delay for one second - * to throttle the allocation rate. If we have tasks - * complete before one second timeout expires then - * taskq_ent_free will signal us and we will - * immediately retry the allocation. - */ - tq->tq_maxalloc_wait++; - rv = cv_timedwait(&tq->tq_maxalloc_cv, - &tq->tq_lock, ddi_get_lbolt() + hz); - tq->tq_maxalloc_wait--; - if (rv > 0) - goto again; /* signaled */ - } - mutex_exit(&tq->tq_lock); - - t = kmem_alloc(sizeof (taskq_ent_t), tqflags); - - mutex_enter(&tq->tq_lock); - if (t != NULL) { - /* Make sure we start without any flags */ - t->tqent_flags = 0; - tq->tq_nalloc++; - } - } - return (t); -} - -static void -task_free(taskq_t *tq, taskq_ent_t *t) -{ - if (tq->tq_nalloc <= tq->tq_minalloc) { - t->tqent_next = tq->tq_freelist; - tq->tq_freelist = t; - } else { - tq->tq_nalloc--; - mutex_exit(&tq->tq_lock); - kmem_free(t, sizeof (taskq_ent_t)); - mutex_enter(&tq->tq_lock); - } - - if (tq->tq_maxalloc_wait) - cv_signal(&tq->tq_maxalloc_cv); -} - -taskqid_t -taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) -{ - taskq_ent_t *t; - - if (taskq_now) { - func(arg); - return (1); - } - - mutex_enter(&tq->tq_lock); - ASSERT(tq->tq_flags & TASKQ_ACTIVE); - if ((t = task_alloc(tq, tqflags)) == NULL) { - mutex_exit(&tq->tq_lock); - return (0); - } - if (tqflags & TQ_FRONT) { - t->tqent_next = tq->tq_task.tqent_next; - t->tqent_prev = &tq->tq_task; - } else { - t->tqent_next = &tq->tq_task; - t->tqent_prev = tq->tq_task.tqent_prev; - } - t->tqent_next->tqent_prev = t; - t->tqent_prev->tqent_next = t; - t->tqent_func = func; - t->tqent_arg = arg; - t->tqent_flags = 0; - cv_signal(&tq->tq_dispatch_cv); - mutex_exit(&tq->tq_lock); - return (1); -} - -taskqid_t -taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags, - clock_t expire_time) -{ - (void) tq, (void) func, (void) arg, (void) tqflags, (void) expire_time; - return (0); -} - -int -taskq_empty_ent(taskq_ent_t *t) -{ - return (t->tqent_next == NULL); -} - -void -taskq_init_ent(taskq_ent_t *t) -{ - t->tqent_next = NULL; - t->tqent_prev = NULL; - t->tqent_func = NULL; - t->tqent_arg = NULL; - t->tqent_flags = 0; -} - -void -taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, - taskq_ent_t *t) -{ - ASSERT(func != NULL); - - /* - * Mark it as a prealloc'd task. This is important - * to ensure that we don't free it later. - */ - t->tqent_flags |= TQENT_FLAG_PREALLOC; - /* - * Enqueue the task to the underlying queue. - */ - mutex_enter(&tq->tq_lock); - - if (flags & TQ_FRONT) { - t->tqent_next = tq->tq_task.tqent_next; - t->tqent_prev = &tq->tq_task; - } else { - t->tqent_next = &tq->tq_task; - t->tqent_prev = tq->tq_task.tqent_prev; - } - t->tqent_next->tqent_prev = t; - t->tqent_prev->tqent_next = t; - t->tqent_func = func; - t->tqent_arg = arg; - cv_signal(&tq->tq_dispatch_cv); - mutex_exit(&tq->tq_lock); -} - -void -taskq_wait(taskq_t *tq) -{ - mutex_enter(&tq->tq_lock); - while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0) - cv_wait(&tq->tq_wait_cv, &tq->tq_lock); - mutex_exit(&tq->tq_lock); -} - -void -taskq_wait_id(taskq_t *tq, taskqid_t id) -{ - (void) id; - taskq_wait(tq); -} - -void -taskq_wait_outstanding(taskq_t *tq, taskqid_t id) -{ - (void) id; - taskq_wait(tq); -} - -static __attribute__((noreturn)) void -taskq_thread(void *arg) -{ - taskq_t *tq = arg; - taskq_ent_t *t; - boolean_t prealloc; - - VERIFY0(pthread_setspecific(taskq_tsd, tq)); - - mutex_enter(&tq->tq_lock); - while (tq->tq_flags & TASKQ_ACTIVE) { - if ((t = tq->tq_task.tqent_next) == &tq->tq_task) { - if (--tq->tq_active == 0) - cv_broadcast(&tq->tq_wait_cv); - cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock); - tq->tq_active++; - continue; - } - t->tqent_prev->tqent_next = t->tqent_next; - t->tqent_next->tqent_prev = t->tqent_prev; - t->tqent_next = NULL; - t->tqent_prev = NULL; - prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC; - mutex_exit(&tq->tq_lock); - - rw_enter(&tq->tq_threadlock, RW_READER); - t->tqent_func(t->tqent_arg); - rw_exit(&tq->tq_threadlock); - - mutex_enter(&tq->tq_lock); - if (!prealloc) - task_free(tq, t); - } - tq->tq_nthreads--; - cv_broadcast(&tq->tq_wait_cv); - mutex_exit(&tq->tq_lock); - thread_exit(); -} - -taskq_t * -taskq_create(const char *name, int nthreads, pri_t pri, - int minalloc, int maxalloc, uint_t flags) -{ - (void) pri; - taskq_t *tq = kmem_zalloc(sizeof (taskq_t), KM_SLEEP); - int t; - - if (flags & TASKQ_THREADS_CPU_PCT) { - int pct; - ASSERT3S(nthreads, >=, 0); - ASSERT3S(nthreads, <=, 100); - pct = MIN(nthreads, 100); - pct = MAX(pct, 0); - - nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100; - nthreads = MAX(nthreads, 1); /* need at least 1 thread */ - } else { - ASSERT3S(nthreads, >=, 1); - } - - rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL); - mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL); - cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); - cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); - cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL); - (void) strlcpy(tq->tq_name, name, sizeof (tq->tq_name)); - tq->tq_flags = flags | TASKQ_ACTIVE; - tq->tq_active = nthreads; - tq->tq_nthreads = nthreads; - tq->tq_minalloc = minalloc; - tq->tq_maxalloc = maxalloc; - tq->tq_task.tqent_next = &tq->tq_task; - tq->tq_task.tqent_prev = &tq->tq_task; - tq->tq_threadlist = kmem_alloc(nthreads * sizeof (kthread_t *), - KM_SLEEP); - - if (flags & TASKQ_PREPOPULATE) { - mutex_enter(&tq->tq_lock); - while (minalloc-- > 0) - task_free(tq, task_alloc(tq, KM_SLEEP)); - mutex_exit(&tq->tq_lock); - } - - for (t = 0; t < nthreads; t++) - VERIFY((tq->tq_threadlist[t] = thread_create_named(tq->tq_name, - NULL, 0, taskq_thread, tq, 0, &p0, TS_RUN, pri)) != NULL); - - return (tq); -} - -void -taskq_destroy(taskq_t *tq) -{ - int nthreads = tq->tq_nthreads; - - taskq_wait(tq); - - mutex_enter(&tq->tq_lock); - - tq->tq_flags &= ~TASKQ_ACTIVE; - cv_broadcast(&tq->tq_dispatch_cv); - - while (tq->tq_nthreads != 0) - cv_wait(&tq->tq_wait_cv, &tq->tq_lock); - - tq->tq_minalloc = 0; - while (tq->tq_nalloc != 0) { - ASSERT(tq->tq_freelist != NULL); - taskq_ent_t *tqent_nexttq = tq->tq_freelist->tqent_next; - task_free(tq, tq->tq_freelist); - tq->tq_freelist = tqent_nexttq; - } - - mutex_exit(&tq->tq_lock); - - kmem_free(tq->tq_threadlist, nthreads * sizeof (kthread_t *)); - - rw_destroy(&tq->tq_threadlock); - mutex_destroy(&tq->tq_lock); - cv_destroy(&tq->tq_dispatch_cv); - cv_destroy(&tq->tq_wait_cv); - cv_destroy(&tq->tq_maxalloc_cv); - - kmem_free(tq, sizeof (taskq_t)); -} - -/* - * Create a taskq with a specified number of pool threads. Allocate - * and return an array of nthreads kthread_t pointers, one for each - * thread in the pool. The array is not ordered and must be freed - * by the caller. - */ -taskq_t * -taskq_create_synced(const char *name, int nthreads, pri_t pri, - int minalloc, int maxalloc, uint_t flags, kthread_t ***ktpp) -{ - taskq_t *tq; - kthread_t **kthreads = kmem_zalloc(sizeof (*kthreads) * nthreads, - KM_SLEEP); - - (void) pri; (void) minalloc; (void) maxalloc; - - flags &= ~(TASKQ_DYNAMIC | TASKQ_THREADS_CPU_PCT | TASKQ_DC_BATCH); - - tq = taskq_create(name, nthreads, minclsyspri, nthreads, INT_MAX, - flags | TASKQ_PREPOPULATE); - VERIFY(tq != NULL); - VERIFY(tq->tq_nthreads == nthreads); - - for (int i = 0; i < nthreads; i++) { - kthreads[i] = tq->tq_threadlist[i]; - } - *ktpp = kthreads; - return (tq); -} - -int -taskq_member(taskq_t *tq, kthread_t *t) -{ - int i; - - if (taskq_now) - return (1); - - for (i = 0; i < tq->tq_nthreads; i++) - if (tq->tq_threadlist[i] == t) - return (1); - - return (0); -} - -taskq_t * -taskq_of_curthread(void) -{ - return (pthread_getspecific(taskq_tsd)); -} - -int -taskq_cancel_id(taskq_t *tq, taskqid_t id) -{ - (void) tq, (void) id; - return (ENOENT); -} - -void -system_taskq_init(void) -{ - VERIFY0(pthread_key_create(&taskq_tsd, NULL)); - system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, - TASKQ_DYNAMIC | TASKQ_PREPOPULATE); - system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, - 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); -} - -void -system_taskq_fini(void) -{ - taskq_destroy(system_taskq); - system_taskq = NULL; /* defensive */ - taskq_destroy(system_delay_taskq); - system_delay_taskq = NULL; - VERIFY0(pthread_key_delete(taskq_tsd)); -} diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c deleted file mode 100644 index 66d6f43967d5..000000000000 --- a/lib/libzpool/util.c +++ /dev/null @@ -1,383 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 by Delphix. All rights reserved. - * Copyright 2017 Jason King - * Copyright (c) 2017, Intel Corporation. - */ - -#include <assert.h> -#include <sys/zfs_context.h> -#include <sys/avl.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/spa.h> -#include <sys/fs/zfs.h> -#include <sys/zfs_refcount.h> -#include <sys/zfs_ioctl.h> -#include <sys/tunables.h> -#include <libzutil.h> - -/* - * Routines needed by more than one client of libzpool. - */ - -static void -show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) -{ - vdev_stat_t *vs; - vdev_stat_t *v0 = { 0 }; - uint64_t sec; - uint64_t is_log = 0; - nvlist_t **child; - uint_t c, children; - char used[6], avail[6]; - char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6]; - - v0 = umem_zalloc(sizeof (*v0), UMEM_NOFAIL); - - if (indent == 0 && desc != NULL) { - (void) printf(" " - " capacity operations bandwidth ---- errors ----\n"); - (void) printf("description " - "used avail read write read write read write cksum\n"); - } - - if (desc != NULL) { - const char *suffix = ""; - const char *bias = NULL; - char bias_suffix[32]; - - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log); - (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_ALLOCATION_BIAS, - &bias); - if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, - (uint64_t **)&vs, &c) != 0) - vs = v0; - - if (bias != NULL) { - (void) snprintf(bias_suffix, sizeof (bias_suffix), - " (%s)", bias); - suffix = bias_suffix; - } else if (is_log) { - suffix = " (log)"; - } - - sec = MAX(1, vs->vs_timestamp / NANOSEC); - - nicenum(vs->vs_alloc, used, sizeof (used)); - nicenum(vs->vs_space - vs->vs_alloc, avail, sizeof (avail)); - nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops, sizeof (rops)); - nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops, sizeof (wops)); - nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes, - sizeof (rbytes)); - nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes, - sizeof (wbytes)); - nicenum(vs->vs_read_errors, rerr, sizeof (rerr)); - nicenum(vs->vs_write_errors, werr, sizeof (werr)); - nicenum(vs->vs_checksum_errors, cerr, sizeof (cerr)); - - (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n", - indent, "", - desc, - (int)(indent+strlen(desc)-25-(vs->vs_space ? 0 : 12)), - suffix, - vs->vs_space ? 6 : 0, vs->vs_space ? used : "", - vs->vs_space ? 6 : 0, vs->vs_space ? avail : "", - rops, wops, rbytes, wbytes, rerr, werr, cerr); - } - umem_free(v0, sizeof (*v0)); - - if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0) - return; - - for (c = 0; c < children; c++) { - nvlist_t *cnv = child[c]; - const char *cname = NULL; - char *tname; - uint64_t np; - int len; - if (nvlist_lookup_string(cnv, ZPOOL_CONFIG_PATH, &cname) && - nvlist_lookup_string(cnv, ZPOOL_CONFIG_TYPE, &cname)) - cname = "<unknown>"; - len = strlen(cname) + 2; - tname = umem_zalloc(len, UMEM_NOFAIL); - (void) strlcpy(tname, cname, len); - if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0) - tname[strlen(tname)] = '0' + np; - show_vdev_stats(tname, ctype, cnv, indent + 2); - umem_free(tname, len); - } -} - -void -show_pool_stats(spa_t *spa) -{ - nvlist_t *config, *nvroot; - const char *name; - - VERIFY0(spa_get_stats(spa_name(spa), &config, NULL, 0)); - - VERIFY0(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot)); - VERIFY0(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name)); - - show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0); - show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0); - show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0); - - nvlist_free(config); -} - -/* - * Common helper for working with libzpool tunables from the command line. - * - * Valid inputs: - * - * <name> show named tunable and value - * <name>=<value> set tunable value - * - * show show all tunables and values - * show=<name> show named tunable and value - * info show info about all tunables - * info=<name> show info about named tunable - */ - -typedef enum { SHOW, INFO, SET } tunable_mode_t; - -static int -list_tunables_cb(const zfs_tunable_t *tunable, void *arg) -{ - const tunable_mode_t *mode = arg; - - static const char *type[] = { - "int", "uint", "ulong", "u64", "str", - }; - static const char *perm[] = { - "rw", "rd", - }; - - if (*mode == SHOW) { - char val[64]; - int err = zfs_tunable_get(tunable, val, sizeof (val)); - if (err == 0) - printf("%s: %s\n", tunable->zt_name, val); - else - printf("%s: [error getting tunable value: %s]\n", - tunable->zt_name, strerror(err)); - } else { - printf("%s [%s %s]: %s\n", tunable->zt_name, - type[tunable->zt_type], perm[tunable->zt_perm], - tunable->zt_desc); - } - - return (0); -} -int -handle_tunable_option(const char *_arg, boolean_t quiet) -{ - int err = 0; - char *arg = strdup(_arg); - char *k, *v; - - v = arg; - k = strsep(&v, "="); - - tunable_mode_t mode; - - if (strcmp(k, "show") == 0) { - mode = SHOW; - k = v; - } else if (strcmp(k, "info") == 0) { - mode = INFO; - k = v; - } else if (v == NULL) { - mode = SHOW; - } else { - mode = SET; - } - - if (quiet && mode != SET) { - err = EINVAL; - goto out; - } - - if (mode == SET) { - const zfs_tunable_t *tunable = zfs_tunable_lookup(k); - if (tunable == NULL) { - err = ENOENT; - goto out; - } - - char vold[256], vnew[256]; - if (zfs_tunable_get(tunable, vold, sizeof (vold)) != 0) - strcpy(vold, "???"); - err = zfs_tunable_set(tunable, v); - if (err != 0) - goto out; - if (zfs_tunable_get(tunable, vnew, sizeof (vnew)) != 0) - strcpy(vnew, "???"); - - if (!quiet) - printf("%s: %s -> %s\n", k, vold, vnew); - } else if (k != NULL) { - const zfs_tunable_t *tunable = zfs_tunable_lookup(k); - if (tunable == NULL) { - err = ENOENT; - goto out; - } - list_tunables_cb(tunable, &mode); - } else { - zfs_tunable_iter(list_tunables_cb, &mode); - } - -out: - if (!quiet) { - if (err == ENOENT) - fprintf(stderr, "no such tunable: %s\n", k); - else if (err != 0) - fprintf(stderr, "couldn't set tunable '%s': %s\n", - k, strerror(err)); - } - - free(arg); - return (err); -} - -static nvlist_t * -refresh_config(void *unused, nvlist_t *tryconfig) -{ - (void) unused; - return (spa_tryimport(tryconfig)); -} - -#if defined(__FreeBSD__) - -#include <sys/param.h> -#include <sys/sysctl.h> -#include <os/freebsd/zfs/sys/zfs_ioctl_compat.h> - -static int -pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive) -{ - (void) unused, (void) guid; - zfs_iocparm_t zp; - zfs_cmd_t *zc = NULL; -#ifdef ZFS_LEGACY_SUPPORT - zfs_cmd_legacy_t *zcl = NULL; -#endif - unsigned long request; - int ret; - - int fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); - if (fd < 0) - return (-1); - - /* - * Use ZFS_IOC_POOL_STATS to check if the pool is active. We want to - * avoid adding a dependency on libzfs_core solely for this ioctl(), - * therefore we manually craft the stats command. Note that the command - * ID is identical between the openzfs and legacy ioctl() formats. - */ - int ver = ZFS_IOCVER_NONE; - size_t ver_size = sizeof (ver); - - sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0); - - switch (ver) { - case ZFS_IOCVER_OZFS: - zc = umem_zalloc(sizeof (zfs_cmd_t), UMEM_NOFAIL); - - (void) strlcpy(zc->zc_name, name, sizeof (zc->zc_name)); - zp.zfs_cmd = (uint64_t)(uintptr_t)zc; - zp.zfs_cmd_size = sizeof (zfs_cmd_t); - zp.zfs_ioctl_version = ZFS_IOCVER_OZFS; - - request = _IOWR('Z', ZFS_IOC_POOL_STATS, zfs_iocparm_t); - ret = ioctl(fd, request, &zp); - - free((void *)(uintptr_t)zc->zc_nvlist_dst); - umem_free(zc, sizeof (zfs_cmd_t)); - - break; -#ifdef ZFS_LEGACY_SUPPORT - case ZFS_IOCVER_LEGACY: - zcl = umem_zalloc(sizeof (zfs_cmd_legacy_t), UMEM_NOFAIL); - - (void) strlcpy(zcl->zc_name, name, sizeof (zcl->zc_name)); - zp.zfs_cmd = (uint64_t)(uintptr_t)zcl; - zp.zfs_cmd_size = sizeof (zfs_cmd_legacy_t); - zp.zfs_ioctl_version = ZFS_IOCVER_LEGACY; - - request = _IOWR('Z', ZFS_IOC_POOL_STATS, zfs_iocparm_t); - ret = ioctl(fd, request, &zp); - - free((void *)(uintptr_t)zcl->zc_nvlist_dst); - umem_free(zcl, sizeof (zfs_cmd_legacy_t)); - - break; -#endif - default: - fprintf(stderr, "unrecognized zfs ioctl version %d", ver); - exit(1); - } - - (void) close(fd); - - *isactive = (ret == 0); - - return (0); -} -#else -static int -pool_active(void *unused, const char *name, uint64_t guid, - boolean_t *isactive) -{ - (void) unused, (void) guid; - int fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); - if (fd < 0) - return (-1); - - /* - * Use ZFS_IOC_POOL_STATS to check if a pool is active. - */ - zfs_cmd_t *zcp = umem_zalloc(sizeof (zfs_cmd_t), UMEM_NOFAIL); - (void) strlcpy(zcp->zc_name, name, sizeof (zcp->zc_name)); - - int ret = ioctl(fd, ZFS_IOC_POOL_STATS, zcp); - - free((void *)(uintptr_t)zcp->zc_nvlist_dst); - umem_free(zcp, sizeof (zfs_cmd_t)); - - (void) close(fd); - - *isactive = (ret == 0); - - return (0); -} -#endif - -pool_config_ops_t libzpool_config_ops = { - .pco_refresh_config = refresh_config, - .pco_pool_active = pool_active, -}; diff --git a/lib/libzpool/vdev_label_os.c b/lib/libzpool/vdev_label_os.c deleted file mode 100644 index 803840884b24..000000000000 --- a/lib/libzpool/vdev_label_os.c +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2023 by iXsystems, Inc. - */ - -#include <sys/zfs_context.h> -#include <sys/spa.h> -#include <sys/spa_impl.h> -#include <sys/vdev.h> -#include <sys/vdev_impl.h> - -/* - * Check if the reserved boot area is in-use. This is called from - * spa_vdev_attach() when adding a device to a raidz vdev, to ensure that the - * reserved area is available as scratch space for raidz expansion. - * - * This function currently always returns 0. On Linux, there are no known - * external uses of the reserved area. On FreeBSD, the reserved boot area is - * used when booting to a ZFS root from an MBR partition. - * - * Currently nothing using libzpool can add a disk to a pool, so this does - * nothing. - */ -int -vdev_check_boot_reserve(spa_t *spa, vdev_t *childvd) -{ - (void) spa; - (void) childvd; - - return (0); -} diff --git a/lib/libzpool/zfs_debug.c b/lib/libzpool/zfs_debug.c deleted file mode 100644 index 3e5cff76abe9..000000000000 --- a/lib/libzpool/zfs_debug.c +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: CDDL-1.0 -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or https://opensource.org/licenses/CDDL-1.0. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. - * Copyright (c) 2024, Rob Norris <robn@despairlabs.com> - */ - -#include <sys/zfs_context.h> - -typedef struct zfs_dbgmsg { - list_node_t zdm_node; - uint64_t zdm_timestamp; - uint_t zdm_size; - char zdm_msg[]; /* variable length allocation */ -} zfs_dbgmsg_t; - -static list_t zfs_dbgmsgs; -static kmutex_t zfs_dbgmsgs_lock; -static uint_t zfs_dbgmsg_size = 0; -static uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */ - -int zfs_dbgmsg_enable = B_TRUE; - -static void -zfs_dbgmsg_purge(uint_t max_size) -{ - while (zfs_dbgmsg_size > max_size) { - zfs_dbgmsg_t *zdm = list_remove_head(&zfs_dbgmsgs); - if (zdm == NULL) - return; - - uint_t size = zdm->zdm_size; - kmem_free(zdm, size); - zfs_dbgmsg_size -= size; - } -} - -void -zfs_dbgmsg_init(void) -{ - list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t), - offsetof(zfs_dbgmsg_t, zdm_node)); - mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL); -} - -void -zfs_dbgmsg_fini(void) -{ - zfs_dbgmsg_t *zdm; - while ((zdm = list_remove_head(&zfs_dbgmsgs))) - umem_free(zdm, zdm->zdm_size); - mutex_destroy(&zfs_dbgmsgs_lock); -} - -void -__set_error(const char *file, const char *func, int line, int err) -{ - if (zfs_flags & ZFS_DEBUG_SET_ERROR) - __dprintf(B_FALSE, file, func, line, "error %lu", - (ulong_t)err); -} - -void -__zfs_dbgmsg(char *buf) -{ - uint_t size = sizeof (zfs_dbgmsg_t) + strlen(buf) + 1; - zfs_dbgmsg_t *zdm = umem_zalloc(size, KM_SLEEP); - zdm->zdm_size = size; - zdm->zdm_timestamp = gethrestime_sec(); - strcpy(zdm->zdm_msg, buf); - - mutex_enter(&zfs_dbgmsgs_lock); - list_insert_tail(&zfs_dbgmsgs, zdm); - zfs_dbgmsg_size += size; - zfs_dbgmsg_purge(zfs_dbgmsg_maxsize); - mutex_exit(&zfs_dbgmsgs_lock); -} - -void -zfs_dbgmsg_print(int fd, const char *tag) -{ - ssize_t ret __attribute__((unused)); - - mutex_enter(&zfs_dbgmsgs_lock); - - /* - * We use write() in this function instead of printf() - * so it is safe to call from a signal handler. - */ - ret = write(fd, "ZFS_DBGMSG(", 11); - ret = write(fd, tag, strlen(tag)); - ret = write(fd, ") START:\n", 9); - - for (zfs_dbgmsg_t *zdm = list_head(&zfs_dbgmsgs); zdm != NULL; - zdm = list_next(&zfs_dbgmsgs, zdm)) { - ret = write(fd, zdm->zdm_msg, strlen(zdm->zdm_msg)); - ret = write(fd, "\n", 1); - } - - ret = write(fd, "ZFS_DBGMSG(", 11); - ret = write(fd, tag, strlen(tag)); - ret = write(fd, ") END\n", 6); - - mutex_exit(&zfs_dbgmsgs_lock); -} diff --git a/lib/libzpool/zfs_racct.c b/lib/libzpool/zfs_racct.c deleted file mode 100644 index 5c9583581d94..000000000000 --- a/lib/libzpool/zfs_racct.c +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * Copyright (c) 2021 iXsystems, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/zfs_racct.h> - -void -zfs_racct_read(spa_t *spa, uint64_t size, uint64_t iops, dmu_flags_t flags) -{ - (void) spa, (void) size, (void) iops, (void) flags; -} - -void -zfs_racct_write(spa_t *spa, uint64_t size, uint64_t iops, dmu_flags_t flags) -{ - (void) spa, (void) size, (void) iops, (void) flags; -} |