git: ba27dd8be821 - main - zfs: merge OpenZFS master-9312e0fd1

O. Hartmann ohartmann at walstatt.org
Mon Feb 22 14:01:52 UTC 2021


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Am Mon, 22 Feb 2021 12:02:04 GMT
Martin Matuska <mm at FreeBSD.org> schrieb:

> The branch main has been updated by mm:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=ba27dd8be821792e15bdabfac69fd6cab0cf9dd3
> 
> commit ba27dd8be821792e15bdabfac69fd6cab0cf9dd3
> Merge: c02a28754bc2 0626917d0786
> Author:     Martin Matuska <mm at FreeBSD.org>
> AuthorDate: 2021-02-22 11:35:56 +0000
> Commit:     Martin Matuska <mm at FreeBSD.org>
> CommitDate: 2021-02-22 12:01:17 +0000
> 
>     zfs: merge OpenZFS master-9312e0fd1
>     
>     Notable upstream changes:
>       778869fa1 Fix reporting of mount progress
>       e7adccf7f Disable use of hardware crypto offload drivers on FreeBSD
>       03e02e5b5 Fix checksum errors not being counted on repeated repair
>       64e0fe14f Restore FreeBSD resource usage accounting
>       11f2e9a49 Fix panic if scrubbing after removing a slog device
>     
>     MFC after:      2 weeks
> 
>  cddl/lib/libzpool/Makefile                         |   1 +
>  stand/libsa/zfs/zstd_shim.c                        |   5 +
>  sys/contrib/openzfs/cmd/zfs/zfs_main.c             |   3 -
>  sys/contrib/openzfs/cmd/ztest/ztest.c              | 113 ++++++++-
>  .../openzfs/include/os/freebsd/spl/sys/uio.h       |  43 +---
>  sys/contrib/openzfs/include/os/linux/spl/sys/uio.h |  22 +-
>  .../include/os/linux/zfs/sys/zfs_context_os.h      |   1 -
>  sys/contrib/openzfs/include/sys/Makefile.am        |   1 +
>  sys/contrib/openzfs/include/sys/spa.h              |   3 +-
>  sys/contrib/openzfs/include/sys/uio_impl.h         |  21 +-
>  sys/contrib/openzfs/include/sys/zfs_context.h      |   3 +-
>  sys/contrib/openzfs/include/sys/zfs_racct.h        |  37 +++
>  sys/contrib/openzfs/lib/libzpool/Makefile.am       |   1 +
>  sys/contrib/openzfs/lib/libzpool/util.c            |  74 ++++--
>  .../lib/libzutil/os/linux/zutil_device_path_os.c   | 252 ++++++++++++---------
>  sys/contrib/openzfs/module/Makefile.bsd            |   1 +
>  .../openzfs/module/os/freebsd/spl/spl_uio.c        |   9 +-
>  .../openzfs/module/os/freebsd/zfs/crypto_os.c      |  15 +-
>  .../openzfs/module/os/freebsd/zfs/zfs_racct.c      |  55 +++++
>  .../openzfs/module/os/linux/zfs/Makefile.in        |   1 +
>  .../openzfs/module/os/linux/zfs/zfs_racct.c        |  36 +++
>  sys/contrib/openzfs/module/zfs/arc.c               |   2 +
>  sys/contrib/openzfs/module/zfs/dmu.c               |   5 +
>  sys/contrib/openzfs/module/zfs/dsl_scan.c          |   6 +-
>  sys/contrib/openzfs/module/zfs/spa_config.c        |   2 +-
>  sys/contrib/openzfs/module/zfs/vdev.c              |   9 +-
>  sys/contrib/openzfs/module/zfs/vdev_indirect.c     |  10 +-
>  sys/contrib/openzfs/module/zfs/vdev_raidz.c        |  20 +-
>  sys/contrib/openzfs/module/zfs/vdev_rebuild.c      |   3 +
>  sys/contrib/openzfs/module/zfs/zfs_fm.c            |  46 +++-
>  sys/contrib/openzfs/module/zfs/zfs_ioctl.c         |   2 +-
>  sys/contrib/openzfs/module/zfs/zfs_vnops.c         |   2 +-
>  sys/contrib/openzfs/module/zfs/zio.c               |  11 +-
>  sys/contrib/openzfs/scripts/zfs.sh                 |   2 +-
>  sys/contrib/openzfs/tests/runfiles/common.run      |   3 +-
>  .../functional/cli_root/zpool_events/Makefile.am   |   3 +-
>  .../zpool_events/zpool_events_clear_retained.ksh   | 135 +++++++++++
>  .../zpool_events/zpool_events_duplicates.ksh       |  11 -
>  sys/modules/zfs/Makefile                           |   1 +
>  sys/modules/zfs/zfs_config.h                       |   2 +-
>  40 files changed, 724 insertions(+), 248 deletions(-)
> 
> diff --cc cddl/lib/libzpool/Makefile
> index d9b2e67094e3,000000000000..6893e31ff20a
> mode 100644,000000..100644
> --- a/cddl/lib/libzpool/Makefile
> +++ b/cddl/lib/libzpool/Makefile
> @@@ -1,266 -1,0 +1,267 @@@
>  +# $FreeBSD$
>  +
>  +ZFSTOP=	${SRCTOP}/sys/contrib/openzfs
>  +
>  +# ZFS_COMMON_SRCS
>  +.PATH: ${ZFSTOP}/module/zfs
>  +.PATH: ${ZFSTOP}/module/zcommon
>  +.PATH: ${ZFSTOP}/module/unicode
>  +# LUA_SRCS
>  +.PATH: ${ZFSTOP}/module/lua
>  +# ZSTD_SRCS
>  +.PATH: ${ZFSTOP}/module/zstd
>  +.PATH: ${ZFSTOP}/module/zstd/lib
>  +
>  +.PATH: ${ZFSTOP}/module/os/linux/zfs
>  +
>  +.PATH: ${ZFSTOP}/lib/libzpool
>  +
>  +.if
> exists(${SRCTOP}/sys/cddl/contrib/opensolaris/common/atomic/${MACHINE_ARCH}/opensolaris_atomic.S)
> +.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/atomic/${MACHINE_ARCH}
> +ATOMIC_SRCS=	opensolaris_atomic.S +ACFLAGS+=	-Wa,--noexecstack
>  +.else
>  +.PATH: ${SRCTOP}/sys/cddl/compat/opensolaris/kern
>  +ATOMIC_SRCS=	opensolaris_atomic.c
>  +.endif
>  +
>  +.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpcspe"
>  +# Don't waste GOT entries on small data.
>  +PICFLAG=	-fPIC
>  +.endif
>  +
>  +LIB=		zpool
>  +
>  +USER_C = \
>  +	kernel.c \
>  +	taskq.c \
>  +	util.c
>  +
>  +KERNEL_C = \
>  +	zfeature_common.c \
>  +	zfs_comutil.c \
>  +	zfs_deleg.c \
>  +	zfs_fletcher.c \
>  +	zfs_fletcher_superscalar.c \
>  +	zfs_fletcher_superscalar4.c \
>  +	zfs_namecheck.c \
>  +	zfs_prop.c \
>  +	zfs_zstd.c \
>  +	zpool_prop.c \
>  +	zprop_common.c \
>  +	abd.c \
>  +	abd_os.c \
>  +	aggsum.c \
>  +	arc.c \
>  +	arc_os.c \
>  +	blkptr.c \
>  +	bplist.c \
>  +	bpobj.c \
>  +	bptree.c \
>  +	btree.c \
>  +	bqueue.c \
>  +	cityhash.c \
>  +	dbuf.c \
>  +	dbuf_stats.c \
>  +	ddt.c \
>  +	ddt_zap.c \
>  +	dmu.c \
>  +	dmu_diff.c \
>  +	dmu_object.c \
>  +	dmu_objset.c \
>  +	dmu_recv.c \
>  +	dmu_redact.c \
>  +	dmu_send.c \
>  +	dmu_traverse.c \
>  +	dmu_tx.c \
>  +	dmu_zfetch.c \
>  +	dnode.c \
>  +	dnode_sync.c \
>  +	dsl_bookmark.c \
>  +	dsl_dataset.c \
>  +	dsl_deadlist.c \
>  +	dsl_deleg.c \
>  +	dsl_dir.c \
>  +	dsl_crypt.c \
>  +	dsl_pool.c \
>  +	dsl_prop.c \
>  +	dsl_scan.c \
>  +	dsl_synctask.c \
>  +	dsl_destroy.c \
>  +	dsl_userhold.c \
>  +	edonr_zfs.c \
>  +	hkdf.c \
>  +	fm.c \
>  +	gzip.c \
>  +	lzjb.c \
>  +	lz4.c \
>  +	metaslab.c \
>  +	mmp.c \
>  +	multilist.c \
>  +	objlist.c \
>  +	pathname.c \
>  +	range_tree.c \
>  +	refcount.c \
>  +	rrwlock.c \
>  +	sa.c \
>  +	sha256.c \
>  +	skein_zfs.c \
>  +	spa.c \
>  +	spa_boot.c \
>  +	spa_checkpoint.c \
>  +	spa_config.c \
>  +	spa_errlog.c \
>  +	spa_history.c \
>  +	spa_log_spacemap.c \
>  +	spa_misc.c \
>  +	spa_stats.c \
>  +	space_map.c \
>  +	space_reftree.c \
>  +	txg.c \
>  +	trace.c \
>  +	uberblock.c \
>  +	unique.c \
>  +	vdev.c \
>  +	vdev_cache.c \
>  +	vdev_draid.c \
>  +	vdev_draid_rand.c \
>  +	vdev_file.c \
>  +	vdev_indirect_births.c \
>  +	vdev_indirect.c \
>  +	vdev_indirect_mapping.c \
>  +	vdev_initialize.c \
>  +	vdev_label.c \
>  +	vdev_mirror.c \
>  +	vdev_missing.c \
>  +	vdev_queue.c \
>  +	vdev_raidz.c \
>  +	vdev_raidz_math_aarch64_neon.c \
>  +	vdev_raidz_math_aarch64_neonx2.c \
>  +	vdev_raidz_math_avx2.c \
>  +	vdev_raidz_math_avx512bw.c \
>  +	vdev_raidz_math_avx512f.c \
>  +	vdev_raidz_math.c \
>  +	vdev_raidz_math_scalar.c \
>  +	vdev_rebuild.c \
>  +	vdev_removal.c \
>  +	vdev_root.c \
>  +	vdev_trim.c \
>  +	zap.c \
>  +	zap_leaf.c \
>  +	zap_micro.c \
>  +	zcp.c \
>  +	zcp_get.c \
>  +	zcp_global.c \
>  +	zcp_iter.c \
>  +	zcp_set.c \
>  +	zcp_synctask.c \
>  +	zfeature.c \
>  +	zfs_byteswap.c \
>  +	zfs_debug.c \
>  +	zfs_fm.c \
>  +	zfs_fuid.c \
>  +	zfs_sa.c \
>  +	zfs_znode.c \
> ++	zfs_racct.c \
>  +	zfs_ratelimit.c \
>  +	zfs_rlock.c \
>  +	zil.c \
>  +	zio.c \
>  +	zio_checksum.c \
>  +	zio_compress.c \
>  +	zio_crypt.c \
>  +	zio_inject.c \
>  +	zle.c \
>  +	zrlock.c \
>  +	zstd.c \
>  +	zthr.c
>  +
>  +ARCH_C =
>  +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
>  +ARCH_C += 	vdev_raidz_math_sse2.c \
>  +		vdev_raidz_math_ssse3.c \
>  +		zfs_fletcher_intel.c \
>  +		zfs_fletcher_sse.c 
>  +CFLAGS +=  -DHAVE_SSE2 	-DHAVE_SSE3
>  +.endif
>  +.if ${MACHINE_ARCH} == "amd64"
>  +ARCH_C +=	zfs_fletcher_avx512.c
>  +CFLAGS+= -DHAVE_AVX2 -DHAVE_AVX -D__x86_64 -DHAVE_AVX512F \
>  +	-DHAVE_AVX512BW
>  +.endif
>  +.if ${MACHINE_CPUARCH} == "aarch64"
>  +ARCH_C +=	zfs_fletcher_aarch64_neon.c
>  +.endif
>  +
>  +LUA_C = \
>  +	lapi.c \
>  +	lauxlib.c \
>  +	lbaselib.c \
>  +	lcode.c \
>  +	lcompat.c \
>  +	lcorolib.c \
>  +	lctype.c \
>  +	ldebug.c \
>  +	ldo.c \
>  +	lfunc.c \
>  +	lgc.c \
>  +	llex.c \
>  +	lmem.c \
>  +	lobject.c \
>  +	lopcodes.c \
>  +	lparser.c \
>  +	lstate.c \
>  +	lstring.c \
>  +	lstrlib.c \
>  +	ltable.c \
>  +	ltablib.c \
>  +	ltm.c \
>  +	lvm.c \
>  +	lzio.c
>  +
>  +UNICODE_C = u8_textprep.c uconv.c
>  +
>  +SRCS=		${USER_C} ${KERNEL_C} ${LUA_C} ${UNICODE_C} ${ARCH_C}
>  +
>  +WARNS?=		2
>  +CFLAGS+= \
>  +	-DIN_BASE \
>  +	-I${ZFSTOP}/include \
>  +	-I${ZFSTOP}/lib/libspl/include \
>  +	-I${ZFSTOP}/lib/libspl/include/os/freebsd \
>  +	-I${SRCTOP}/sys \
>  +	-I${ZFSTOP}/include/os/freebsd/zfs \
>  +	-I${SRCTOP}/cddl/compat/opensolaris/include \
>  +	-I${ZFSTOP}/module/icp/include \
>  +	-include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h \
>  +	-DHAVE_ISSETUGID \
>  +	-include ${SRCTOP}/sys/modules/zfs/zfs_config.h \
>  +	-I${SRCTOP}/sys/modules/zfs \
>  +	-I${ZFSTOP}/include/os/freebsd/zfs \
>  +	-DLIB_ZPOOL_BUILD -DZFS_DEBUG \
>  +
>  +# XXX: pthread doesn't have mutex_owned() equivalent, so we need to look
>  +#      into libthr private structures. That's sooo evil, but it's only for
>  +#      ZFS debugging tools needs.
>  +CFLAGS+=	-DWANTS_MUTEX_OWNED
>  +CFLAGS+=	-I${SRCTOP}/lib/libpthread/thread
>  +CFLAGS+=	-I${SRCTOP}/lib/libpthread/sys
>  +CFLAGS+=	-I${SRCTOP}/lib/libthr/arch/${MACHINE_CPUARCH}/include
>  +CFLAGS.gcc+=	-fms-extensions
>  +
>  +LIBADD=		md pthread z spl icp nvpair avl umem
>  +
>  +# atomic.S doesn't like profiling.
>  +MK_PROFILE=	no
>  +
>  +CSTD=	c99
>  +
>  +# Since there are many asserts in this library, it makes no sense to compile
>  +# it without debugging.
>  +
>  +CFLAGS+=	-g -DDEBUG=1
>  +
>  +CFLAGS.zfs_zstd.c=	-Wno-cast-qual -Wno-pointer-arith
>  +CFLAGS.zstd.c+=	-fno-tree-vectorize
>  +
>  +.include <bsd.lib.mk>
> diff --cc stand/libsa/zfs/zstd_shim.c
> index b94df6f51913,000000000000..91f5171a72b5
> mode 100644,000000..100644
> --- a/stand/libsa/zfs/zstd_shim.c
> +++ b/stand/libsa/zfs/zstd_shim.c
> @@@ -1,40 -1,0 +1,45 @@@
>  +/*-
>  + * Copyright (c) 2020 M. Warner Losh <imp at FreeBSD.org>
>  + *
>  + * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
>  +__FBSDID("$FreeBSD$");
>  +
>  +/*
>  + * Small amount of shim code needed to get zfs_zstd.c to compile. These items
>  + * here should all be defined in the SPL or as part of libstand somewhere, but
>  + * aren't for reasons that haven't been tracked down yet. Ideally, they would
>  + * all go away and we'd compile zfs_zstd.c directly. Based on an original by
>  + * Matt Macey, but only the #include remains untouched from that.
>  + */
>  +
>  +#define ZFS_MODULE_PARAM_ARGS void
>  +typedef int boolean_t;	/* This one may be tough to get rid of */
>  +
> ++/* TODO: openzfs/include/sys/uio_impl.h must not be included */
> ++#ifndef _SYS_UIO_IMPL_H
> ++#define _SYS_UIO_IMPL_H
> ++#endif
> ++
>  +#include <contrib/openzfs/module/zstd/zfs_zstd.c>
> diff --cc sys/contrib/openzfs/include/sys/zfs_racct.h
> index 000000000000,cfcdd336ea42..cfcdd336ea42
> mode 000000,100644..100644
> --- a/sys/contrib/openzfs/include/sys/zfs_racct.h
> +++ b/sys/contrib/openzfs/include/sys/zfs_racct.h
> diff --cc sys/contrib/openzfs/module/os/freebsd/zfs/zfs_racct.c
> index 000000000000,b46cc046268e..b46cc046268e
> mode 000000,100644..100644
> --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_racct.c
> +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_racct.c
> diff --cc sys/contrib/openzfs/module/os/linux/zfs/zfs_racct.c
> index 000000000000,7897e0f9edc1..7897e0f9edc1
> mode 000000,100644..100644
> --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_racct.c
> +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_racct.c
> diff --cc sys/contrib/openzfs/module/zfs/zfs_ioctl.c
> index 0e35fd069cbb,000000000000..922253469fba
> mode 100644,000000..100644
> --- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
> +++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
> @@@ -1,7688 -1,0 +1,7688 @@@
>  +/*
>  + * CDDL HEADER START
>  + *
>  + * The contents of this file are subject to the terms of the
>  + * Common Development and Distribution License (the "License").
>  + * You may not use this file except in compliance with the License.
>  + *
>  + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
>  + * or http://www.opensolaris.org/os/licensing.
>  + * See the License for the specific language governing permissions
>  + * and limitations under the License.
>  + *
>  + * When distributing Covered Code, include this CDDL HEADER in each
>  + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
>  + * If applicable, add the following below this CDDL HEADER, with the
>  + * fields enclosed by brackets "[]" replaced with your own identifying
>  + * information: Portions Copyright [yyyy] [name of copyright owner]
>  + *
>  + * CDDL HEADER END
>  + */
>  +
>  +/*
>  + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
>  + * Portions Copyright 2011 Martin Matuska
>  + * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
>  + * Portions Copyright 2012 Pawel Jakub Dawidek <pawel at dawidek.net>
>  + * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
>  + * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
>  + * Copyright (c) 2014, Joyent, Inc. All rights reserved.
>  + * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
>  + * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
>  + * Copyright (c) 2013 Steven Hartland. All rights reserved.
>  + * Copyright (c) 2014 Integros [integros.com]
>  + * Copyright 2016 Toomas Soome <tsoome at me.com>
>  + * Copyright (c) 2016 Actifio, Inc. All rights reserved.
>  + * Copyright (c) 2018, loli10K <ezomori.nozomu at gmail.com>. All rights reserved.
>  + * Copyright 2017 RackTop Systems.
>  + * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
>  + * Copyright (c) 2019 Datto Inc.
>  + * Copyright (c) 2019, 2020 by Christian Schwarz. All rights reserved.
>  + * Copyright (c) 2019, Klara Inc.
>  + * Copyright (c) 2019, Allan Jude
>  + */
>  +
>  +/*
>  + * ZFS ioctls.
>  + *
>  + * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
>  + * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
>  + *
>  + * There are two ways that we handle ioctls: the legacy way where almost
>  + * all of the logic is in the ioctl callback, and the new way where most
>  + * of the marshalling is handled in the common entry point, zfsdev_ioctl().
>  + *
>  + * Non-legacy ioctls should be registered by calling
>  + * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
>  + * from userland by lzc_ioctl().
>  + *
>  + * The registration arguments are as follows:
>  + *
>  + * const char *name
>  + *   The name of the ioctl.  This is used for history logging.  If the
>  + *   ioctl returns successfully (the callback returns 0), and allow_log
>  + *   is true, then a history log entry will be recorded with the input &
>  + *   output nvlists.  The log entry can be printed with "zpool history -i".
>  + *
>  + * zfs_ioc_t ioc
>  + *   The ioctl request number, which userland will pass to ioctl(2).
>  + *   We want newer versions of libzfs and libzfs_core to run against
>  + *   existing zfs kernel modules (i.e. a deferred reboot after an update).
>  + *   Therefore the ioctl numbers cannot change from release to release.
>  + *
>  + * zfs_secpolicy_func_t *secpolicy
>  + *   This function will be called before the zfs_ioc_func_t, to
>  + *   determine if this operation is permitted.  It should return EPERM
>  + *   on failure, and 0 on success.  Checks include determining if the
>  + *   dataset is visible in this zone, and if the user has either all
>  + *   zfs privileges in the zone (SYS_MOUNT), or has been granted permission
>  + *   to do this operation on this dataset with "zfs allow".
>  + *
>  + * zfs_ioc_namecheck_t namecheck
>  + *   This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
>  + *   name, a dataset name, or nothing.  If the name is not well-formed,
>  + *   the ioctl will fail and the callback will not be called.
>  + *   Therefore, the callback can assume that the name is well-formed
>  + *   (e.g. is null-terminated, doesn't have more than one '@' character,
>  + *   doesn't have invalid characters).
>  + *
>  + * zfs_ioc_poolcheck_t pool_check
>  + *   This specifies requirements on the pool state.  If the pool does
>  + *   not meet them (is suspended or is readonly), the ioctl will fail
>  + *   and the callback will not be called.  If any checks are specified
>  + *   (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
>  + *   Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
>  + *   POOL_CHECK_READONLY).
>  + *
>  + * zfs_ioc_key_t *nvl_keys
>  + *  The list of expected/allowable innvl input keys. This list is used
>  + *  to validate the nvlist input to the ioctl.
>  + *
>  + * boolean_t smush_outnvlist
>  + *   If smush_outnvlist is true, then the output is presumed to be a
>  + *   list of errors, and it will be "smushed" down to fit into the
>  + *   caller's buffer, by removing some entries and replacing them with a
>  + *   single "N_MORE_ERRORS" entry indicating how many were removed.  See
>  + *   nvlist_smush() for details.  If smush_outnvlist is false, and the
>  + *   outnvlist does not fit into the userland-provided buffer, then the
>  + *   ioctl will fail with ENOMEM.
>  + *
>  + * zfs_ioc_func_t *func
>  + *   The callback function that will perform the operation.
>  + *
>  + *   The callback should return 0 on success, or an error number on
>  + *   failure.  If the function fails, the userland ioctl will return -1,
>  + *   and errno will be set to the callback's return value.  The callback
>  + *   will be called with the following arguments:
>  + *
>  + *   const char *name
>  + *     The name of the pool or dataset to operate on, from
>  + *     zfs_cmd_t:zc_name.  The 'namecheck' argument specifies the
>  + *     expected type (pool, dataset, or none).
>  + *
>  + *   nvlist_t *innvl
>  + *     The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src.  Or
>  + *     NULL if no input nvlist was provided.  Changes to this nvlist are
>  + *     ignored.  If the input nvlist could not be deserialized, the
>  + *     ioctl will fail and the callback will not be called.
>  + *
>  + *   nvlist_t *outnvl
>  + *     The output nvlist, initially empty.  The callback can fill it in,
>  + *     and it will be returned to userland by serializing it into
>  + *     zfs_cmd_t:zc_nvlist_dst.  If it is non-empty, and serialization
>  + *     fails (e.g. because the caller didn't supply a large enough
>  + *     buffer), then the overall ioctl will fail.  See the
>  + *     'smush_nvlist' argument above for additional behaviors.
>  + *
>  + *     There are two typical uses of the output nvlist:
>  + *       - To return state, e.g. property values.  In this case,
>  + *         smush_outnvlist should be false.  If the buffer was not large
>  + *         enough, the caller will reallocate a larger buffer and try
>  + *         the ioctl again.
>  + *
>  + *       - To return multiple errors from an ioctl which makes on-disk
>  + *         changes.  In this case, smush_outnvlist should be true.
>  + *         Ioctls which make on-disk modifications should generally not
>  + *         use the outnvl if they succeed, because the caller can not
>  + *         distinguish between the operation failing, and
>  + *         deserialization failing.
>  + *
>  + * IOCTL Interface Errors
>  + *
>  + * The following ioctl input errors can be returned:
>  + *   ZFS_ERR_IOC_CMD_UNAVAIL	the ioctl number is not supported by kernel
>  + *   ZFS_ERR_IOC_ARG_UNAVAIL	an input argument is not supported by kernel
>  + *   ZFS_ERR_IOC_ARG_REQUIRED	a required input argument is missing
>  + *   ZFS_ERR_IOC_ARG_BADTYPE	an input argument has an invalid type
>  + */
>  +
>  +#include <sys/types.h>
>  +#include <sys/param.h>
>  +#include <sys/errno.h>
> - #include <sys/uio.h>
> ++#include <sys/uio_impl.h>
>  +#include <sys/file.h>
>  +#include <sys/kmem.h>
>  +#include <sys/cmn_err.h>
>  +#include <sys/stat.h>
>  +#include <sys/zfs_ioctl.h>
>  +#include <sys/zfs_quota.h>
>  +#include <sys/zfs_vfsops.h>
>  +#include <sys/zfs_znode.h>
>  +#include <sys/zap.h>
>  +#include <sys/spa.h>
>  +#include <sys/spa_impl.h>
>  +#include <sys/vdev.h>
>  +#include <sys/vdev_impl.h>
>  +#include <sys/dmu.h>
>  +#include <sys/dsl_dir.h>
>  +#include <sys/dsl_dataset.h>
>  +#include <sys/dsl_prop.h>
>  +#include <sys/dsl_deleg.h>
>  +#include <sys/dmu_objset.h>
>  +#include <sys/dmu_impl.h>
>  +#include <sys/dmu_redact.h>
>  +#include <sys/dmu_tx.h>
>  +#include <sys/sunddi.h>
>  +#include <sys/policy.h>
>  +#include <sys/zone.h>
>  +#include <sys/nvpair.h>
>  +#include <sys/pathname.h>
>  +#include <sys/fs/zfs.h>
>  +#include <sys/zfs_ctldir.h>
>  +#include <sys/zfs_dir.h>
>  +#include <sys/zfs_onexit.h>
>  +#include <sys/zvol.h>
>  +#include <sys/dsl_scan.h>
>  +#include <sys/fm/util.h>
>  +#include <sys/dsl_crypt.h>
>  +#include <sys/rrwlock.h>
>  +#include <sys/zfs_file.h>
>  +
>  +#include <sys/dmu_recv.h>
>  +#include <sys/dmu_send.h>
>  +#include <sys/dmu_recv.h>
>  +#include <sys/dsl_destroy.h>
>  +#include <sys/dsl_bookmark.h>
>  +#include <sys/dsl_userhold.h>
>  +#include <sys/zfeature.h>
>  +#include <sys/zcp.h>
>  +#include <sys/zio_checksum.h>
>  +#include <sys/vdev_removal.h>
>  +#include <sys/vdev_impl.h>
>  +#include <sys/vdev_initialize.h>
>  +#include <sys/vdev_trim.h>
>  +
>  +#include "zfs_namecheck.h"
>  +#include "zfs_prop.h"
>  +#include "zfs_deleg.h"
>  +#include "zfs_comutil.h"
>  +
>  +#include <sys/lua/lua.h>
>  +#include <sys/lua/lauxlib.h>
>  +#include <sys/zfs_ioctl_impl.h>
>  +
>  +kmutex_t zfsdev_state_lock;
>  +zfsdev_state_t *zfsdev_state_list;
>  +
>  +/*
>  + * Limit maximum nvlist size.  We don't want users passing in insane values
>  + * for zc->zc_nvlist_src_size, since we will need to allocate that much memory.
>  + * Defaults to 0=auto which is handled by platform code.
>  + */
>  +unsigned long zfs_max_nvlist_src_size = 0;
>  +
>  +/*
>  + * When logging the output nvlist of an ioctl in the on-disk history, limit
>  + * the logged size to this many bytes.  This must be less then DMU_MAX_ACCESS.
>  + * This applies primarily to zfs_ioc_channel_program().
>  + */
>  +unsigned long zfs_history_output_max = 1024 * 1024;
>  +
>  +uint_t zfs_fsyncer_key;
>  +uint_t zfs_allow_log_key;
>  +
>  +/* DATA_TYPE_ANY is used when zkey_type can vary. */
>  +#define	DATA_TYPE_ANY	DATA_TYPE_UNKNOWN
>  +
>  +typedef struct zfs_ioc_vec {
>  +	zfs_ioc_legacy_func_t	*zvec_legacy_func;
>  +	zfs_ioc_func_t		*zvec_func;
>  +	zfs_secpolicy_func_t	*zvec_secpolicy;
>  +	zfs_ioc_namecheck_t	zvec_namecheck;
>  +	boolean_t		zvec_allow_log;
>  +	zfs_ioc_poolcheck_t	zvec_pool_check;
>  +	boolean_t		zvec_smush_outnvlist;
>  +	const char		*zvec_name;
>  +	const zfs_ioc_key_t	*zvec_nvl_keys;
>  +	size_t			zvec_nvl_key_count;
>  +} zfs_ioc_vec_t;
>  +
>  +/* This array is indexed by zfs_userquota_prop_t */
>  +static const char *userquota_perms[] = {
>  +	ZFS_DELEG_PERM_USERUSED,
>  +	ZFS_DELEG_PERM_USERQUOTA,
>  +	ZFS_DELEG_PERM_GROUPUSED,
>  +	ZFS_DELEG_PERM_GROUPQUOTA,
>  +	ZFS_DELEG_PERM_USEROBJUSED,
>  +	ZFS_DELEG_PERM_USEROBJQUOTA,
>  +	ZFS_DELEG_PERM_GROUPOBJUSED,
>  +	ZFS_DELEG_PERM_GROUPOBJQUOTA,
>  +	ZFS_DELEG_PERM_PROJECTUSED,
>  +	ZFS_DELEG_PERM_PROJECTQUOTA,
>  +	ZFS_DELEG_PERM_PROJECTOBJUSED,
>  +	ZFS_DELEG_PERM_PROJECTOBJQUOTA,
>  +};
>  +
>  +static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
>  +static int zfs_ioc_id_quota_upgrade(zfs_cmd_t *zc);
>  +static int zfs_check_settable(const char *name, nvpair_t *property,
>  +    cred_t *cr);
>  +static int zfs_check_clearable(const char *dataset, nvlist_t *props,
>  +    nvlist_t **errors);
>  +static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
>  +    boolean_t *);
>  +int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
>  +static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
>  +
>  +static void
>  +history_str_free(char *buf)
>  +{
>  +	kmem_free(buf, HIS_MAX_RECORD_LEN);
>  +}
>  +
>  +static char *
>  +history_str_get(zfs_cmd_t *zc)
>  +{
>  +	char *buf;
>  +
>  +	if (zc->zc_history == 0)
>  +		return (NULL);
>  +
>  +	buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
>  +	if (copyinstr((void *)(uintptr_t)zc->zc_history,
>  +	    buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
>  +		history_str_free(buf);
>  +		return (NULL);
>  +	}
>  +
>  +	buf[HIS_MAX_RECORD_LEN -1] = '\0';
>  +
>  +	return (buf);
>  +}
>  +
>  +/*
>  + * Return non-zero if the spa version is less than requested version.
>  + */
>  +static int
>  +zfs_earlier_version(const char *name, int version)
>  +{
>  +	spa_t *spa;
>  +
>  +	if (spa_open(name, &spa, FTAG) == 0) {
>  +		if (spa_version(spa) < version) {
>  +			spa_close(spa, FTAG);
>  +			return (1);
>  +		}
>  +		spa_close(spa, FTAG);
>  +	}
>  +	return (0);
>  +}
>  +
>  +/*
>  + * Return TRUE if the ZPL version is less than requested version.
>  + */
>  +static boolean_t
>  +zpl_earlier_version(const char *name, int version)
>  +{
>  +	objset_t *os;
>  +	boolean_t rc = B_TRUE;
>  +
>  +	if (dmu_objset_hold(name, FTAG, &os) == 0) {
>  +		uint64_t zplversion;
>  +
>  +		if (dmu_objset_type(os) != DMU_OST_ZFS) {
>  +			dmu_objset_rele(os, FTAG);
>  +			return (B_TRUE);
>  +		}
>  +		/* XXX reading from non-owned objset */
>  +		if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
>  +			rc = zplversion < version;
>  +		dmu_objset_rele(os, FTAG);
>  +	}
>  +	return (rc);
>  +}
>  +
>  +static void
>  +zfs_log_history(zfs_cmd_t *zc)
>  +{
>  +	spa_t *spa;
>  +	char *buf;
>  +
>  +	if ((buf = history_str_get(zc)) == NULL)
>  +		return;
>  +
>  +	if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
>  +		if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
>  +			(void) spa_history_log(spa, buf);
>  +		spa_close(spa, FTAG);
>  +	}
>  +	history_str_free(buf);
>  +}
>  +
>  +/*
>  + * Policy for top-level read operations (list pools).  Requires no privileges,
>  + * and can be used in the local zone, as there is no associated dataset.
>  + */
>  +/* ARGSUSED */
>  +static int
>  +zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
>  +{
>  +	return (0);
>  +}
>  +
>  +/*
>  + * Policy for dataset read operations (list children, get statistics).  Requires
>  + * no privileges, but must be visible in the local zone.
>  + */
>  +/* ARGSUSED */
>  +static int
>  +zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
>  +{
>  +	if (INGLOBALZONE(curproc) ||
>  +	    zone_dataset_visible(zc->zc_name, NULL))
>  +		return (0);
>  +
>  +	return (SET_ERROR(ENOENT));
>  +}
>  +
>  +static int
>  +zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
>  +{
>  +	int writable = 1;
>  +
>  +	/*
>  +	 * The dataset must be visible by this zone -- check this first
>  +	 * so they don't see EPERM on something they shouldn't know about.
>  +	 */
>  +	if (!INGLOBALZONE(curproc) &&
>  +	    !zone_dataset_visible(dataset, &writable))
>  +		return (SET_ERROR(ENOENT));
>  +
>  +	if (INGLOBALZONE(curproc)) {
>  +		/*
>  +		 * If the fs is zoned, only root can access it from the
>  +		 * global zone.
>  +		 */
>  +		if (secpolicy_zfs(cr) && zoned)
>  +			return (SET_ERROR(EPERM));
>  +	} else {
>  +		/*
>  +		 * If we are in a local zone, the 'zoned' property must be set.
>  +		 */
>  +		if (!zoned)
>  +			return (SET_ERROR(EPERM));
>  +
>  +		/* must be writable by this zone */
>  +		if (!writable)
>  +			return (SET_ERROR(EPERM));
>  +	}
>  +	return (0);
>  +}
>  +
>  +static int
>  +zfs_dozonecheck(const char *dataset, cred_t *cr)
>  +{
>  +	uint64_t zoned;
>  +
>  +	if (dsl_prop_get_integer(dataset, zfs_prop_to_name(ZFS_PROP_ZONED),
>  +	    &zoned, NULL))
>  +		return (SET_ERROR(ENOENT));
>  +
>  +	return (zfs_dozonecheck_impl(dataset, zoned, cr));
>  +}
>  +
>  +static int
>  +zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
>  +{
>  +	uint64_t zoned;
>  +
>  +	if (dsl_prop_get_int_ds(ds, zfs_prop_to_name(ZFS_PROP_ZONED), &zoned))
>  +		return (SET_ERROR(ENOENT));
>  +
>  +	return (zfs_dozonecheck_impl(dataset, zoned, cr));
>  +}
>  +
>  +static int
>  +zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
>  +    const char *perm, cred_t *cr)
>  +{
>  +	int error;
>  +
>  +	error = zfs_dozonecheck_ds(name, ds, cr);
>  +	if (error == 0) {
>  +		error = secpolicy_zfs(cr);
>  +		if (error != 0)
>  +			error = dsl_deleg_access_impl(ds, perm, cr);
>  +	}
>  +	return (error);
>  +}
>  +
>  +static int
>  +zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
>  +{
>  +	int error;
>  +	dsl_dataset_t *ds;
>  +	dsl_pool_t *dp;
>  +
>  +	/*
>  +	 * First do a quick check for root in the global zone, which
>  +	 * is allowed to do all write_perms.  This ensures that zfs_ioc_*
>  +	 * will get to handle nonexistent datasets.
>  +	 */
>  +	if (INGLOBALZONE(curproc) && secpolicy_zfs(cr) == 0)
>  +		return (0);
>  +
>  +	error = dsl_pool_hold(name, FTAG, &dp);
>  +	if (error != 0)
>  +		return (error);
>  +
>  +	error = dsl_dataset_hold(dp, name, FTAG, &ds);
>  +	if (error != 0) {
>  +		dsl_pool_rele(dp, FTAG);
>  +		return (error);
>  +	}
>  +
>  +	error = zfs_secpolicy_write_perms_ds(name, ds, perm, cr);
>  +
>  +	dsl_dataset_rele(ds, FTAG);
>  +	dsl_pool_rele(dp, FTAG);
>  +	return (error);
>  +}
>  +
>  +/*
>  + * Policy for setting the security label property.
>  + *
>  + * Returns 0 for success, non-zero for access and other errors.
>  + */
>  +static int
>  +zfs_set_slabel_policy(const char *name, const char *strval, cred_t *cr)
>  +{
>  +#ifdef HAVE_MLSLABEL
>  +	char		ds_hexsl[MAXNAMELEN];
>  +	bslabel_t	ds_sl, new_sl;
>  +	boolean_t	new_default = FALSE;
>  +	uint64_t	zoned;
>  +	int		needed_priv = -1;
>  +	int		error;
>  +
>  +	/* First get the existing dataset label. */
>  +	error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
>  +	    1, sizeof (ds_hexsl), &ds_hexsl, NULL);
>  +	if (error != 0)
>  +		return (SET_ERROR(EPERM));
>  +
>  +	if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
>  +		new_default = TRUE;
>  +
>  +	/* The label must be translatable */
>  +	if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
>  +		return (SET_ERROR(EINVAL));
>  +
>  +	/*
>  +	 * In a non-global zone, disallow attempts to set a label that
>  +	 * doesn't match that of the zone; otherwise no other checks
>  +	 * are needed.
>  +	 */
>  +	if (!INGLOBALZONE(curproc)) {
>  +		if (new_default || !blequal(&new_sl, CR_SL(CRED())))
>  +			return (SET_ERROR(EPERM));
>  +		return (0);
>  +	}
>  +
>  +	/*
>  +	 * For global-zone datasets (i.e., those whose zoned property is
>  +	 * "off", verify that the specified new label is valid for the
>  +	 * global zone.
>  +	 */
>  +	if (dsl_prop_get_integer(name,
>  +	    zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
>  +		return (SET_ERROR(EPERM));
>  +	if (!zoned) {
>  +		if (zfs_check_global_label(name, strval) != 0)
>  +			return (SET_ERROR(EPERM));
>  +	}
>  +
>  +	/*
>  +	 * If the existing dataset label is nondefault, check if the
>  +	 * dataset is mounted (label cannot be changed while mounted).
>  +	 * Get the zfsvfs_t; if there isn't one, then the dataset isn't
>  +	 * mounted (or isn't a dataset, doesn't exist, ...).
>  +	 */
>  +	if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
>  +		objset_t *os;
>  +		static const char *setsl_tag = "setsl_tag";
>  +
>  +		/*
>  +		 * Try to own the dataset; abort if there is any error,
>  +		 * (e.g., already mounted, in use, or other error).
>  +		 */
>  +		error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE, B_TRUE,
>  +		    setsl_tag, &os);
>  +		if (error != 0)
>  +			return (SET_ERROR(EPERM));
>  +
>  +		dmu_objset_disown(os, B_TRUE, setsl_tag);
>  +
>  +		if (new_default) {
>  +			needed_priv = PRIV_FILE_DOWNGRADE_SL;
> *** 13292 LINES SKIPPED ***
> _______________________________________________
> dev-commits-src-main at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
> To unsubscribe, send any mail to "dev-commits-src-main-unsubscribe at freebsd.org"

On FreeBSD 14-CURRENT, with ZFS statically builtin the kernel, this commit renders "make
buildkernel" to fail:

[...]

===> cam (all)
- --- kernel ---
ld: error: undefined symbol: zfs_racct_read
>>> referenced by arc.c
>>>               arc.o:(arc_read)
- --- modules-all ---
- --- all_subdir_cardbus ---
===> cardbus (all)
- --- kernel ---

ld: error: undefined symbol: zfs_racct_write
>>> referenced by dmu.c
>>>               dmu.o:(dmu_buf_hold_array_by_dnode)
>>> referenced by dmu.c
>>>               dmu.o:(dmu_assign_arcbuf_by_dnode)
*** [kernel] Error code 1

make[2]: stopped in /usr/obj/usr/src/amd64.amd64/sys/CURRENT14
- --- modules-all ---
*** [modules-all] Error code 6



- -- 
O. Hartmann

Ich widerspreche der Nutzung oder Übermittlung meiner Daten für
Werbezwecke oder für die Markt- oder Meinungsforschung (§ 28 Abs. 4 BDSG).
-----BEGIN PGP SIGNATURE-----

iHUEARYIAB0WIQSy8IBxAPDkqVBaTJ44N1ZZPba5RwUCYDO5RgAKCRA4N1ZZPba5
Rz4/AQDhhbsIWQYZ3ZgrMfzSs0m410Cpvo5mzOU1yIH3PIXJ1AD/bUPx/RUhEuYX
17WmQR5+uuUL9w1/rTNWps5baPHmaAw=
=7igt
-----END PGP SIGNATURE-----


More information about the dev-commits-src-all mailing list