The branch vendor/openzfs has been updated by mm:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9162a1ce3ae9158ae75ab1835e30ac14d3b6899c

commit 9162a1ce3ae9158ae75ab1835e30ac14d3b6899c
Author:     Martin Matuska <[email protected]>
AuthorDate: 2021-03-13 17:30:04 +0000
Commit:     Martin Matuska <[email protected]>
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@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 ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to