git: 9162a1ce3ae9 - vendor/openzfs - Update vendor/openzfs to master-9305ff2ed
Martin Matuska
mm at FreeBSD.org
Sat Mar 13 17:33:02 UTC 2021
The branch vendor/openzfs has been updated by mm:
URL: https://cgit.FreeBSD.org/src/commit/?id=9162a1ce3ae9158ae75ab1835e30ac14d3b6899c
commit 9162a1ce3ae9158ae75ab1835e30ac14d3b6899c
Author: Martin Matuska <mm at FreeBSD.org>
AuthorDate: 2021-03-13 17:30:04 +0000
Commit: Martin Matuska <mm at FreeBSD.org>
CommitDate: 2021-03-13 17:30:04 +0000
Update vendor/openzfs to master-9305ff2ed
Notable upstream pull request merges:
#11153 Scalable teardown lock for FreeBSD
#11651 Don't bomb out when using keylocation=file://
#11667 zvol: call zil_replaying() during replay
#11683 abd_get_offset_struct() may allocate new abd
#11693 Intentionally allow ZFS_READONLY in zfs_write
#11716 zpool import cachefile improvements
#11720 FreeBSD: Clean up zfsdev_close to match Linux
#11730 FreeBSD: bring back possibility to rewind the
checkpoint from bootloader
---
.github/workflows/checkstyle.yaml | 2 +-
cmd/vdev_id/vdev_id | 9 +-
cmd/zpool/zpool_main.c | 307 +++++++++++++--------
cmd/zstream/zstream_redup.c | 1 +
config/zfs-build.m4 | 36 +++
configure.ac | 1 +
include/os/freebsd/spl/sys/Makefile.am | 3 +
include/os/freebsd/spl/sys/debug.h | 80 +++---
include/os/freebsd/zfs/sys/zfs_vfsops_os.h | 118 ++++++--
include/os/freebsd/zfs/sys/zfs_znode_impl.h | 10 +-
include/os/linux/spl/sys/debug.h | 78 +++---
include/os/linux/zfs/sys/zfs_vfsops_os.h | 33 +++
include/os/linux/zfs/sys/zfs_znode_impl.h | 10 +-
include/sys/dmu_redact.h | 2 +
include/sys/zfs_ioctl.h | 1 -
lib/libzfs/libzfs_crypto.c | 10 +-
lib/libzfs/libzfs_mount.c | 25 +-
lib/libzfs/os/freebsd/libzfs_zmount.c | 5 +-
lib/libzfs/os/linux/libzfs_mount_os.c | 6 +-
lib/libzutil/zutil_import.c | 177 +++++++++---
man/man8/zfs-receive.8 | 10 +
man/man8/zfs-send.8 | 7 +-
module/Makefile.in | 5 +
module/os/freebsd/zfs/kmod_core.c | 18 +-
module/os/freebsd/zfs/zfs_dir.c | 5 +-
module/os/freebsd/zfs/zfs_vfsops.c | 65 +++--
module/os/freebsd/zfs/zfs_vnops_os.c | 61 +---
module/os/freebsd/zfs/zfs_znode.c | 2 +-
module/os/freebsd/zfs/zvol_os.c | 9 +-
module/os/linux/zfs/zfs_acl.c | 26 +-
module/os/linux/zfs/zfs_vfsops.c | 18 +-
module/os/linux/zfs/zio_crypt.c | 1 +
module/os/linux/zfs/zvol_os.c | 102 +++++--
module/zcommon/zfs_prop.c | 2 +-
module/zfs/abd.c | 6 +-
module/zfs/spa_misc.c | 4 +-
module/zfs/zfs_ioctl.c | 10 +-
module/zfs/zfs_vnops.c | 6 +-
module/zfs/zvol.c | 15 +-
tests/runfiles/common.run | 1 +
tests/zfs-tests/include/commands.cfg | 2 +-
tests/zfs-tests/include/libtest.shlib | 19 +-
tests/zfs-tests/include/tunables.cfg | 8 +-
.../functional/cli_root/zpool/zpool_002_pos.ksh | 37 ++-
.../functional/cli_root/zpool/zpool_003_pos.ksh | 39 ++-
.../functional/cli_root/zpool_import/Makefile.am | 1 +
.../import_cachefile_paths_changed.ksh | 117 ++++++++
.../tests/functional/events/events_002_pos.ksh | 7 +-
.../tests/functional/xattr/xattr_003_neg.ksh | 44 +--
49 files changed, 1063 insertions(+), 498 deletions(-)
diff --git a/.github/workflows/checkstyle.yaml b/.github/workflows/checkstyle.yaml
index 1707f5bb21db..8dcd5047a748 100644
--- a/.github/workflows/checkstyle.yaml
+++ b/.github/workflows/checkstyle.yaml
@@ -6,7 +6,7 @@ on:
jobs:
checkstyle:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-18.04
steps:
- uses: actions/checkout at v2
with:
diff --git a/cmd/vdev_id/vdev_id b/cmd/vdev_id/vdev_id
index 8a379a72690e..d8918da1078c 100755
--- a/cmd/vdev_id/vdev_id
+++ b/cmd/vdev_id/vdev_id
@@ -298,8 +298,15 @@ sas_handler() {
# Utilize DM device name to gather subordinate block devices
# using sysfs to avoid userspace utilities
- DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
+
+ # If our DEVNAME is something like /dev/dm-177, then we may be
+ # able to get our DMDEV from it.
+ DMDEV=$(echo $DEVNAME | sed 's;/dev/;;g')
+ if [ ! -e /sys/block/$DMDEV/slaves/* ] ; then
+ # It's not there, try looking in /dev/mapper
+ DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
awk '{gsub("../", " "); print $NF}')
+ fi
# Use sysfs pointers in /sys/block/dm-X/slaves because using
# userspace tools creates lots of overhead and should be avoided
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index e89eb3bea770..e23604b3d81c 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -2623,8 +2623,8 @@ print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
/*
* Display the status for the given pool.
*/
-static void
-show_import(nvlist_t *config)
+static int
+show_import(nvlist_t *config, boolean_t report_error)
{
uint64_t pool_state;
vdev_stat_t *vs;
@@ -2656,6 +2656,13 @@ show_import(nvlist_t *config)
reason = zpool_import_status(config, &msgid, &errata);
+ /*
+ * If we're importing using a cachefile, then we won't report any
+ * errors unless we are in the scan phase of the import.
+ */
+ if (reason != ZPOOL_STATUS_OK && !report_error)
+ return (reason);
+
(void) printf(gettext(" pool: %s\n"), name);
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
(void) printf(gettext(" state: %s"), health);
@@ -2983,6 +2990,7 @@ show_import(nvlist_t *config)
"be part of this pool, though their\n\texact "
"configuration cannot be determined.\n"));
}
+ return (0);
}
static boolean_t
@@ -3121,6 +3129,121 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
return (ret);
}
+static int
+import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
+ char *orig_name, char *new_name,
+ boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all,
+ importargs_t *import)
+{
+ nvlist_t *config = NULL;
+ nvlist_t *found_config = NULL;
+ uint64_t pool_state;
+
+ /*
+ * At this point we have a list of import candidate configs. Even if
+ * we were searching by pool name or guid, we still need to
+ * post-process the list to deal with pool state and possible
+ * duplicate names.
+ */
+ int err = 0;
+ nvpair_t *elem = NULL;
+ boolean_t first = B_TRUE;
+ while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
+
+ verify(nvpair_value_nvlist(elem, &config) == 0);
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &pool_state) == 0);
+ if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
+ continue;
+ if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
+ continue;
+
+ verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
+ import->policy) == 0);
+
+ if (!pool_specified) {
+ if (first)
+ first = B_FALSE;
+ else if (!do_all)
+ (void) printf("\n");
+
+ if (do_all) {
+ err |= do_import(config, NULL, mntopts,
+ props, flags);
+ } else {
+ /*
+ * If we're importing from cachefile, then
+ * we don't want to report errors until we
+ * are in the scan phase of the import. If
+ * we get an error, then we return that error
+ * to invoke the scan phase.
+ */
+ if (import->cachefile && !import->scan)
+ err = show_import(config, B_FALSE);
+ else
+ (void) show_import(config, B_TRUE);
+ }
+ } else if (import->poolname != NULL) {
+ char *name;
+
+ /*
+ * We are searching for a pool based on name.
+ */
+ verify(nvlist_lookup_string(config,
+ ZPOOL_CONFIG_POOL_NAME, &name) == 0);
+
+ if (strcmp(name, import->poolname) == 0) {
+ if (found_config != NULL) {
+ (void) fprintf(stderr, gettext(
+ "cannot import '%s': more than "
+ "one matching pool\n"),
+ import->poolname);
+ (void) fprintf(stderr, gettext(
+ "import by numeric ID instead\n"));
+ err = B_TRUE;
+ }
+ found_config = config;
+ }
+ } else {
+ uint64_t guid;
+
+ /*
+ * Search for a pool by guid.
+ */
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
+
+ if (guid == import->guid)
+ found_config = config;
+ }
+ }
+
+ /*
+ * If we were searching for a specific pool, verify that we found a
+ * pool, and then do the import.
+ */
+ if (pool_specified && err == 0) {
+ if (found_config == NULL) {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "no such pool available\n"), orig_name);
+ err = B_TRUE;
+ } else {
+ err |= do_import(found_config, new_name,
+ mntopts, props, flags);
+ }
+ }
+
+ /*
+ * If we were just looking for pools, report an error if none were
+ * found.
+ */
+ if (!pool_specified && first)
+ (void) fprintf(stderr,
+ gettext("no pools available to import\n"));
+ return (err);
+}
+
typedef struct target_exists_args {
const char *poolname;
uint64_t poolguid;
@@ -3248,51 +3371,54 @@ zpool_do_checkpoint(int argc, char **argv)
/*
* zpool import [-d dir] [-D]
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
- * [-d dir | -c cachefile] [-f] -a
+ * [-d dir | -c cachefile | -s] [-f] -a
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
- * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
+ * [-d dir | -c cachefile | -s] [-f] [-n] [-F] <pool | id>
+ * [newpool]
*
- * -c Read pool information from a cachefile instead of searching
- * devices.
+ * -c Read pool information from a cachefile instead of searching
+ * devices. If importing from a cachefile config fails, then
+ * fallback to searching for devices only in the directories that
+ * exist in the cachefile.
*
- * -d Scan in a specific directory, other than /dev/. More than
+ * -d Scan in a specific directory, other than /dev/. More than
* one directory can be specified using multiple '-d' options.
*
- * -D Scan for previously destroyed pools or import all or only
- * specified destroyed pools.
+ * -D Scan for previously destroyed pools or import all or only
+ * specified destroyed pools.
*
- * -R Temporarily import the pool, with all mountpoints relative to
+ * -R Temporarily import the pool, with all mountpoints relative to
* the given root. The pool will remain exported when the machine
* is rebooted.
*
- * -V Import even in the presence of faulted vdevs. This is an
- * intentionally undocumented option for testing purposes, and
- * treats the pool configuration as complete, leaving any bad
+ * -V Import even in the presence of faulted vdevs. This is an
+ * intentionally undocumented option for testing purposes, and
+ * treats the pool configuration as complete, leaving any bad
* vdevs in the FAULTED state. In other words, it does verbatim
* import.
*
- * -f Force import, even if it appears that the pool is active.
+ * -f Force import, even if it appears that the pool is active.
*
- * -F Attempt rewind if necessary.
+ * -F Attempt rewind if necessary.
*
- * -n See if rewind would work, but don't actually rewind.
+ * -n See if rewind would work, but don't actually rewind.
*
- * -N Import the pool but don't mount datasets.
+ * -N Import the pool but don't mount datasets.
*
- * -T Specify a starting txg to use for import. This option is
- * intentionally undocumented option for testing purposes.
+ * -T Specify a starting txg to use for import. This option is
+ * intentionally undocumented option for testing purposes.
*
- * -a Import all pools found.
+ * -a Import all pools found.
*
- * -l Load encryption keys while importing.
+ * -l Load encryption keys while importing.
*
- * -o Set property=value and/or temporary mount options (without '=').
+ * -o Set property=value and/or temporary mount options (without '=').
*
- * -s Scan using the default search path, the libblkid cache will
- * not be consulted.
+ * -s Scan using the default search path, the libblkid cache will
+ * not be consulted.
*
- * --rewind-to-checkpoint
- * Import the pool and revert back to the checkpoint.
+ * --rewind-to-checkpoint
+ * Import the pool and revert back to the checkpoint.
*
* The import command scans for pools to import, and import pools based on pool
* name and GUID. The pool can also be renamed as part of the import process.
@@ -3309,15 +3435,11 @@ zpool_do_import(int argc, char **argv)
boolean_t do_all = B_FALSE;
boolean_t do_destroyed = B_FALSE;
char *mntopts = NULL;
- nvpair_t *elem;
- nvlist_t *config;
uint64_t searchguid = 0;
char *searchname = NULL;
char *propval;
- nvlist_t *found_config;
nvlist_t *policy = NULL;
nvlist_t *props = NULL;
- boolean_t first;
int flags = ZFS_IMPORT_NORMAL;
uint32_t rewind_policy = ZPOOL_NO_REWIND;
boolean_t dryrun = B_FALSE;
@@ -3325,7 +3447,8 @@ zpool_do_import(int argc, char **argv)
boolean_t xtreme_rewind = B_FALSE;
boolean_t do_scan = B_FALSE;
boolean_t pool_exists = B_FALSE;
- uint64_t pool_state, txg = -1ULL;
+ boolean_t pool_specified = B_FALSE;
+ uint64_t txg = -1ULL;
char *cachefile = NULL;
importargs_t idata = { 0 };
char *endptr;
@@ -3447,6 +3570,11 @@ zpool_do_import(int argc, char **argv)
usage(B_FALSE);
}
+ if (cachefile && do_scan) {
+ (void) fprintf(stderr, gettext("-c is incompatible with -s\n"));
+ usage(B_FALSE);
+ }
+
if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
(void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
usage(B_FALSE);
@@ -3527,7 +3655,7 @@ zpool_do_import(int argc, char **argv)
searchname = argv[0];
searchguid = 0;
}
- found_config = NULL;
+ pool_specified = B_TRUE;
/*
* User specified a name or guid. Ensure it's unique.
@@ -3606,98 +3734,33 @@ zpool_do_import(int argc, char **argv)
return (1);
}
+ err = import_pools(pools, props, mntopts, flags, argv[0],
+ argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
+ do_all, &idata);
+
/*
- * At this point we have a list of import candidate configs. Even if
- * we were searching by pool name or guid, we still need to
- * post-process the list to deal with pool state and possible
- * duplicate names.
+ * If we're using the cachefile and we failed to import, then
+ * fallback to scanning the directory for pools that match
+ * those in the cachefile.
*/
- err = 0;
- elem = NULL;
- first = B_TRUE;
- while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
-
- verify(nvpair_value_nvlist(elem, &config) == 0);
-
- verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
- &pool_state) == 0);
- if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
- continue;
- if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
- continue;
-
- verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
- policy) == 0);
-
- if (argc == 0) {
- if (first)
- first = B_FALSE;
- else if (!do_all)
- (void) printf("\n");
-
- if (do_all) {
- err |= do_import(config, NULL, mntopts,
- props, flags);
- } else {
- show_import(config);
- }
- } else if (searchname != NULL) {
- char *name;
-
- /*
- * We are searching for a pool based on name.
- */
- verify(nvlist_lookup_string(config,
- ZPOOL_CONFIG_POOL_NAME, &name) == 0);
+ if (err != 0 && cachefile != NULL) {
+ (void) printf(gettext("cachefile import failed, retrying\n"));
- if (strcmp(name, searchname) == 0) {
- if (found_config != NULL) {
- (void) fprintf(stderr, gettext(
- "cannot import '%s': more than "
- "one matching pool\n"), searchname);
- (void) fprintf(stderr, gettext(
- "import by numeric ID instead\n"));
- err = B_TRUE;
- }
- found_config = config;
- }
- } else {
- uint64_t guid;
-
- /*
- * Search for a pool by guid.
- */
- verify(nvlist_lookup_uint64(config,
- ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
-
- if (guid == searchguid)
- found_config = config;
- }
- }
+ /*
+ * We use the scan flag to gather the directories that exist
+ * in the cachefile. If we need to fallback to searching for
+ * the pool config, we will only search devices in these
+ * directories.
+ */
+ idata.scan = B_TRUE;
+ nvlist_free(pools);
+ pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
- /*
- * If we were searching for a specific pool, verify that we found a
- * pool, and then do the import.
- */
- if (argc != 0 && err == 0) {
- if (found_config == NULL) {
- (void) fprintf(stderr, gettext("cannot import '%s': "
- "no such pool available\n"), argv[0]);
- err = B_TRUE;
- } else {
- err |= do_import(found_config, argc == 1 ? NULL :
- argv[1], mntopts, props, flags);
- }
+ err = import_pools(pools, props, mntopts, flags, argv[0],
+ argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
+ do_all, &idata);
}
- /*
- * If we were just looking for pools, report an error if none were
- * found.
- */
- if (argc == 0 && first)
- (void) fprintf(stderr,
- gettext("no pools available to import\n"));
-
error:
nvlist_free(props);
nvlist_free(pools);
@@ -7785,8 +7848,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
* do not print estimated time if hours_left is more than
* 30 days
*/
- (void) printf(gettext(" %s copied out of %s at %s/s, "
- "%.2f%% done"),
+ (void) printf(gettext(
+ "\t%s copied out of %s at %s/s, %.2f%% done"),
examined_buf, total_buf, rate_buf, 100 * fraction_done);
if (hours_left < (30 * 24)) {
(void) printf(gettext(", %lluh%um to go\n"),
@@ -7801,8 +7864,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
if (prs->prs_mapping_memory > 0) {
char mem_buf[7];
zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
- (void) printf(gettext(" %s memory used for "
- "removed device mappings\n"),
+ (void) printf(gettext(
+ "\t%s memory used for removed device mappings\n"),
mem_buf);
}
}
diff --git a/cmd/zstream/zstream_redup.c b/cmd/zstream/zstream_redup.c
index 41f1068e3dfc..15dd8a1ed126 100644
--- a/cmd/zstream/zstream_redup.c
+++ b/cmd/zstream/zstream_redup.c
@@ -248,6 +248,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
fflags &= ~(DMU_BACKUP_FEATURE_DEDUP |
DMU_BACKUP_FEATURE_DEDUPPROPS);
+ /* cppcheck-suppress syntaxError */
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
int sz = drr->drr_payloadlen;
diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
index 305d0c6936b2..cd5996c0424c 100644
--- a/config/zfs-build.m4
+++ b/config/zfs-build.m4
@@ -11,6 +11,7 @@ AC_DEFUN([ZFS_AC_DEBUG_ENABLE], [
DEBUG_CPPFLAGS="-DDEBUG -UNDEBUG"
DEBUG_LDFLAGS=""
DEBUG_ZFS="_with_debug"
+ WITH_DEBUG="true"
AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled])
KERNEL_DEBUG_CFLAGS="-Werror"
@@ -22,6 +23,7 @@ AC_DEFUN([ZFS_AC_DEBUG_DISABLE], [
DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG"
DEBUG_LDFLAGS=""
DEBUG_ZFS="_without_debug"
+ WITH_DEBUG=""
KERNEL_DEBUG_CFLAGS=""
KERNEL_DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG"
@@ -51,6 +53,7 @@ AC_DEFUN([ZFS_AC_DEBUG], [
AC_SUBST(DEBUG_CPPFLAGS)
AC_SUBST(DEBUG_LDFLAGS)
AC_SUBST(DEBUG_ZFS)
+ AC_SUBST(WITH_DEBUG)
AC_SUBST(KERNEL_DEBUG_CFLAGS)
AC_SUBST(KERNEL_DEBUG_CPPFLAGS)
@@ -152,6 +155,39 @@ AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [
AC_MSG_RESULT([$enable_debug_kmem_tracking])
])
+AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD], [
+ AS_IF([sysctl -n kern.conftxt | fgrep -qx $'options\tINVARIANTS'],
+ [enable_invariants="yes"],
+ [enable_invariants="no"])
+])
+
+AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT], [
+ AM_COND_IF([BUILD_FREEBSD],
+ [ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD],
+ [enable_invariants="no"])
+])
+
+dnl #
+dnl # Detected for the running kernel by default, enables INVARIANTS features
+dnl # in the FreeBSD kernel module. This feature must be used when building
+dnl # for a FreeBSD kernel with "options INVARIANTS" in the KERNCONF and must
+dnl # not be used when the INVARIANTS option is absent.
+dnl #
+AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS], [
+ AC_MSG_CHECKING([whether FreeBSD kernel INVARIANTS checks are enabled])
+ AC_ARG_ENABLE([invariants],
+ [AS_HELP_STRING([--enable-invariants],
+ [Enable FreeBSD kernel INVARIANTS checks [[default: detect]]])],
+ [], [ZFS_AC_DEBUG_INVARIANTS_DETECT])
+
+ AS_IF([test "x$enable_invariants" = xyes],
+ [WITH_INVARIANTS="true"],
+ [WITH_INVARIANTS=""])
+ AC_SUBST(WITH_INVARIANTS)
+
+ AC_MSG_RESULT([$enable_invariants])
+])
+
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
AX_COUNT_CPUS([])
AC_SUBST(CPU_COUNT)
diff --git a/configure.ac b/configure.ac
index b2d88554ed7d..07f590b390bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,6 +61,7 @@ ZFS_AC_DEBUG
ZFS_AC_DEBUGINFO
ZFS_AC_DEBUG_KMEM
ZFS_AC_DEBUG_KMEM_TRACKING
+ZFS_AC_DEBUG_INVARIANTS
AC_CONFIG_FILES([
Makefile
diff --git a/include/os/freebsd/spl/sys/Makefile.am b/include/os/freebsd/spl/sys/Makefile.am
index ca45b42b6b8d..6bee47830d9c 100644
--- a/include/os/freebsd/spl/sys/Makefile.am
+++ b/include/os/freebsd/spl/sys/Makefile.am
@@ -4,6 +4,7 @@ KERNEL_H = \
atomic.h \
byteorder.h \
callb.h \
+ ccompat.h \
ccompile.h \
cmn_err.h \
condvar.h \
@@ -18,9 +19,11 @@ KERNEL_H = \
fcntl.h \
file.h \
freebsd_rwlock.h \
+ idmap.h \
inttypes.h \
isa_defs.h \
kmem_cache.h \
+ kidmap.h \
kmem.h \
kstat.h \
list_impl.h \
diff --git a/include/os/freebsd/spl/sys/debug.h b/include/os/freebsd/spl/sys/debug.h
index 2751f57801f7..1f820bc3345f 100644
--- a/include/os/freebsd/spl/sys/debug.h
+++ b/include/os/freebsd/spl/sys/debug.h
@@ -68,65 +68,65 @@ void spl_dumpstack(void);
#define PANIC(fmt, a...) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
-#define VERIFY(cond) \
- (void) (unlikely(!(cond)) && \
+#define VERIFY(cond) \
+ (void) (unlikely(!(cond)) && \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"%s", "VERIFY(" #cond ") failed\n"))
-#define VERIFY3B(LEFT, OP, RIGHT) do { \
- boolean_t _verify3_left = (boolean_t)(LEFT); \
- boolean_t _verify3_right = (boolean_t)(RIGHT); \
- if (!(_verify3_left OP _verify3_right)) \
+#define VERIFY3B(LEFT, OP, RIGHT) do { \
+ const boolean_t _verify3_left = (boolean_t)(LEFT); \
+ const boolean_t _verify3_right = (boolean_t)(RIGHT);\
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
- "failed (%d " #OP " %d)\n", \
- (boolean_t) (_verify3_left), \
- (boolean_t) (_verify3_right)); \
+ "failed (%d " #OP " %d)\n", \
+ (boolean_t) (_verify3_left), \
+ (boolean_t) (_verify3_right)); \
} while (0)
-#define VERIFY3S(LEFT, OP, RIGHT) do { \
- int64_t _verify3_left = (int64_t)(LEFT); \
- int64_t _verify3_right = (int64_t)(RIGHT); \
- if (!(_verify3_left OP _verify3_right)) \
+#define VERIFY3S(LEFT, OP, RIGHT) do { \
+ const int64_t _verify3_left = (int64_t)(LEFT); \
+ const int64_t _verify3_right = (int64_t)(RIGHT); \
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
- "failed (%lld " #OP " %lld)\n", \
- (long long) (_verify3_left), \
- (long long) (_verify3_right)); \
+ "failed (%lld " #OP " %lld)\n", \
+ (long long) (_verify3_left), \
+ (long long) (_verify3_right)); \
} while (0)
-#define VERIFY3U(LEFT, OP, RIGHT) do { \
- uint64_t _verify3_left = (uint64_t)(LEFT); \
- uint64_t _verify3_right = (uint64_t)(RIGHT); \
- if (!(_verify3_left OP _verify3_right)) \
+#define VERIFY3U(LEFT, OP, RIGHT) do { \
+ const uint64_t _verify3_left = (uint64_t)(LEFT); \
+ const uint64_t _verify3_right = (uint64_t)(RIGHT); \
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
- "failed (%llu " #OP " %llu)\n", \
- (unsigned long long) (_verify3_left), \
- (unsigned long long) (_verify3_right)); \
+ "failed (%llu " #OP " %llu)\n", \
+ (unsigned long long) (_verify3_left), \
+ (unsigned long long) (_verify3_right)); \
} while (0)
-#define VERIFY3P(LEFT, OP, RIGHT) do { \
- uintptr_t _verify3_left = (uintptr_t)(LEFT); \
- uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
- if (!(_verify3_left OP _verify3_right)) \
+#define VERIFY3P(LEFT, OP, RIGHT) do { \
+ const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
+ const uintptr_t _verify3_right = (uintptr_t)(RIGHT);\
+ if (unlikely(!(_verify3_left OP _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
- "failed (%px " #OP " %px)\n", \
- (void *) (_verify3_left), \
- (void *) (_verify3_right)); \
+ "failed (%px " #OP " %px)\n", \
+ (void *) (_verify3_left), \
+ (void *) (_verify3_right)); \
} while (0)
-#define VERIFY0(RIGHT) do { \
- int64_t _verify3_left = (int64_t)(0); \
- int64_t _verify3_right = (int64_t)(RIGHT); \
- if (!(_verify3_left == _verify3_right)) \
+#define VERIFY0(RIGHT) do { \
+ const int64_t _verify3_left = (int64_t)(0); \
+ const int64_t _verify3_right = (int64_t)(RIGHT); \
+ if (unlikely(!(_verify3_left == _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
- "VERIFY3(0 == " #RIGHT ") " \
- "failed (0 == %lld)\n", \
- (long long) (_verify3_right)); \
+ "VERIFY3(0 == " #RIGHT ") " \
+ "failed (0 == %lld)\n", \
+ (long long) (_verify3_right)); \
} while (0)
-#define CTASSERT_GLOBAL(x) CTASSERT(x)
+#define CTASSERT_GLOBAL(x) CTASSERT(x)
/*
* Debugging disabled (--disable-debug)
@@ -154,11 +154,11 @@ void spl_dumpstack(void);
#define ASSERT0 VERIFY0
#define ASSERT VERIFY
#define IMPLY(A, B) \
- ((void)(((!(A)) || (B)) || \
+ ((void)(likely((!(A)) || (B)) || \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"(" #A ") implies (" #B ")")))
#define EQUIV(A, B) \
- ((void)((!!(A) == !!(B)) || \
+ ((void)(likely(!!(A) == !!(B)) || \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
"(" #A ") is equivalent to (" #B ")")))
/* END CSTYLED */
diff --git a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
index c7f464d034bd..a263b48f7517 100644
--- a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
+++ b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
@@ -27,6 +27,10 @@
#ifndef _SYS_FS_ZFS_VFSOPS_H
#define _SYS_FS_ZFS_VFSOPS_H
+#if __FreeBSD_version >= 1300125
+#define TEARDOWN_RMS
+#endif
+
#if __FreeBSD_version >= 1300109
#define TEARDOWN_INACTIVE_RMS
#endif
@@ -46,10 +50,16 @@
extern "C" {
#endif
-#ifdef TEARDOWN_INACTIVE_RMS
+#ifdef TEARDOWN_RMS
typedef struct rmslock zfs_teardown_lock_t;
#else
-#define zfs_teardown_lock_t krwlock_t
+#define zfs_teardown_lock_t rrmlock_t
+#endif
+
+#ifdef TEARDOWN_INACTIVE_RMS
+typedef struct rmslock zfs_teardown_inactive_lock_t;
+#else
+#define zfs_teardown_inactive_lock_t krwlock_t
#endif
typedef struct zfsvfs zfsvfs_t;
@@ -80,8 +90,8 @@ struct zfsvfs {
int z_norm; /* normalization flags */
boolean_t z_atime; /* enable atimes mount option */
boolean_t z_unmounted; /* unmounted */
- rrmlock_t z_teardown_lock;
- zfs_teardown_lock_t z_teardown_inactive_lock;
+ zfs_teardown_lock_t z_teardown_lock;
+ zfs_teardown_inactive_lock_t z_teardown_inactive_lock;
list_t z_all_znodes; /* all vnodes in the fs */
uint64_t z_nr_znodes; /* number of znodes in the fs */
kmutex_t z_znodes_lock; /* lock for z_all_znodes */
@@ -112,53 +122,121 @@ struct zfsvfs {
struct task z_unlinked_drain_task;
};
+#ifdef TEARDOWN_RMS
+#define ZFS_TEARDOWN_INIT(zfsvfs) \
+ rms_init(&(zfsvfs)->z_teardown_lock, "zfs teardown")
+
+#define ZFS_TEARDOWN_DESTROY(zfsvfs) \
+ rms_destroy(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_TRY_ENTER_READ(zfsvfs) \
+ rms_try_rlock(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag) \
+ rms_rlock(&(zfsvfs)->z_teardown_lock);
+
+#define ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag) \
+ rms_runlock(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, tag) \
+ rms_wlock(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_EXIT_WRITE(zfsvfs) \
+ rms_wunlock(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_EXIT(zfsvfs, tag) \
+ rms_unlock(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_READ_HELD(zfsvfs) \
+ rms_rowned(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_WRITE_HELD(zfsvfs) \
+ rms_wowned(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_HELD(zfsvfs) \
+ rms_owned_any(&(zfsvfs)->z_teardown_lock)
+#else
+#define ZFS_TEARDOWN_INIT(zfsvfs) \
+ rrm_init(&(zfsvfs)->z_teardown_lock, B_FALSE)
+
+#define ZFS_TEARDOWN_DESTROY(zfsvfs) \
+ rrm_destroy(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_TRY_ENTER_READ(zfsvfs) \
+ rw_tryenter(&(zfsvfs)->z_teardown_lock, RW_READER)
+
+#define ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag) \
+ rrm_enter_read(&(zfsvfs)->z_teardown_lock, tag);
+
+#define ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag) \
+ rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
+
+#define ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, tag) \
+ rrm_enter(&(zfsvfs)->z_teardown_lock, RW_WRITER, tag)
+
+#define ZFS_TEARDOWN_EXIT_WRITE(zfsvfs) \
+ rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
+
+#define ZFS_TEARDOWN_EXIT(zfsvfs, tag) \
+ rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
+
+#define ZFS_TEARDOWN_READ_HELD(zfsvfs) \
+ RRM_READ_HELD(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_WRITE_HELD(zfsvfs) \
+ RRM_WRITE_HELD(&(zfsvfs)->z_teardown_lock)
+
+#define ZFS_TEARDOWN_HELD(zfsvfs) \
+ RRM_LOCK_HELD(&(zfsvfs)->z_teardown_lock)
+#endif
+
#ifdef TEARDOWN_INACTIVE_RMS
-#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_INIT(zfsvfs) \
rms_init(&(zfsvfs)->z_teardown_inactive_lock, "zfs teardown inactive")
-#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs) \
rms_destroy(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_TRY_ENTER_READ(zfsvfs) \
rms_try_rlock(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_ENTER_READ(zfsvfs) \
rms_rlock(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_EXIT_READ(zfsvfs) \
rms_runlock(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_ENTER_WRITE(zfsvfs) \
rms_wlock(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_EXIT_WRITE(zfsvfs) \
rms_wunlock(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_WRITE_HELD(zfsvfs) \
rms_wowned(&(zfsvfs)->z_teardown_inactive_lock)
#else
-#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_INIT(zfsvfs) \
rw_init(&(zfsvfs)->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL)
-#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs) \
rw_destroy(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_TRY_ENTER_READ(zfsvfs) \
rw_tryenter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
-#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_ENTER_READ(zfsvfs) \
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
-#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_EXIT_READ(zfsvfs) \
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_ENTER_WRITE(zfsvfs) \
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_WRITER)
-#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_EXIT_WRITE(zfsvfs) \
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
-#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
+#define ZFS_TEARDOWN_INACTIVE_WRITE_HELD(zfsvfs) \
RW_WRITE_HELD(&(zfsvfs)->z_teardown_inactive_lock)
#endif
diff --git a/include/os/freebsd/zfs/sys/zfs_znode_impl.h b/include/os/freebsd/zfs/sys/zfs_znode_impl.h
index 186afa9b2b39..d7cdb360c2bc 100644
--- a/include/os/freebsd/zfs/sys/zfs_znode_impl.h
+++ b/include/os/freebsd/zfs/sys/zfs_znode_impl.h
@@ -124,19 +124,19 @@ extern minor_t zfsdev_minor_alloc(void);
/* Called on entry to each ZFS vnode and vfs operation */
#define ZFS_ENTER(zfsvfs) \
{ \
- rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
- if ((zfsvfs)->z_unmounted) { \
- ZFS_EXIT(zfsvfs); \
+ ZFS_TEARDOWN_ENTER_READ((zfsvfs), FTAG); \
+ if (__predict_false((zfsvfs)->z_unmounted)) { \
+ ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
return (EIO); \
} \
}
/* Must be called before exiting the vop */
-#define ZFS_EXIT(zfsvfs) rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG)
+#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG)
/* Verifies the znode is valid */
#define ZFS_VERIFY_ZP(zp) \
- if ((zp)->z_sa_hdl == NULL) { \
+ if (__predict_false((zp)->z_sa_hdl == NULL)) { \
ZFS_EXIT((zp)->z_zfsvfs); \
return (EIO); \
} \
diff --git a/include/os/linux/spl/sys/debug.h b/include/os/linux/spl/sys/debug.h
index 46da5c783397..dc6b85eebff7 100644
*** 2070 LINES SKIPPED ***
More information about the dev-commits-src-all
mailing list