diff --git a/.github/workflows/macos-build.yaml b/.github/workflows/macos-build.yaml new file mode 100644 index 000000000000..de387c9adbfd --- /dev/null +++ b/.github/workflows/macos-build.yaml @@ -0,0 +1,54 @@ +name: Build on macOS +on: push + +jobs: + build: + runs-on: macos-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + #- name: csrutil disable + # run: | + # sudo csrutil disable + #- name: csrutil enable + # run: | + # sudo csrutil enable --without kext + #- name: spctl kext-consent disable + # run: | + # sudo spctl kext-consent disable + - name: install deps + run: | + brew install automake libtool gawk coreutils + - name: install deps + run: | + #brew install openssl@3 + - name: autogen + run: | + ./autogen.sh + - name: configure + run: | + #https://stackoverflow.com/a/62591864 + ./configure CPPFLAGS="-I/usr/local/opt/gettext/include -I/usr/local/opt/openssl/include" LDFLAGS="-L/usr/local/opt/gettext/lib/ -L/usr/local/opt/openssl/lib" + - name: build + run: | + make -j 2 + #- name: install + # run: | + # sudo make install DESTDIR=/// + + #- name: load + # run: | + # sudo kextload -v /Library/Extensions/zfs.kext + + #- name: ls + # run: | + # sudo ls -Rla + # ls -Rla + #- name: rsync + # run: | + # rsync -avx --exclude /out/ ${{github.workspace}}/ ${{github.workspace}}/out/ --no-links + #- name: Upload dev build + # uses: actions/upload-artifact@v3.1.0 + # with: + # name: dev_build + # path: ${{github.workspace}}/out/* diff --git a/Makefile.am b/Makefile.am index 11e45dae8255..5c6f339d8464 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,6 +18,12 @@ if BUILD_LINUX include $(srcdir)/%D%/rpm/Makefile.am endif +if BUILD_MACOS +bin_PROGRAMS= +noinst_PROGRAMS= +include $(srcdir)/%D%/module/os/macos/Makefile.am +endif + if CONFIG_USER include $(srcdir)/%D%/cmd/Makefile.am include $(srcdir)/%D%/contrib/Makefile.am @@ -194,11 +200,12 @@ cscopelist: PHONY += tags tags: ctags etags -PHONY += pkg pkg-dkms pkg-kmod pkg-utils +PHONY += pkg pkg-dkms pkg-kmod pkg-utils pkg-macos pkg: @DEFAULT_PACKAGE@ pkg-dkms: @DEFAULT_PACKAGE@-dkms pkg-kmod: @DEFAULT_PACKAGE@-kmod pkg-utils: @DEFAULT_PACKAGE@-utils +pkg-macos: @DEFAULT_PACKAGE@-macos include config/rpm.am include config/deb.am diff --git a/cmd/Makefile.am b/cmd/Makefile.am index 6d6de4adb42a..a6c288274657 100644 --- a/cmd/Makefile.am +++ b/cmd/Makefile.am @@ -98,6 +98,10 @@ SHELLCHECKSCRIPTS += %D%/zvol_wait include $(srcdir)/%D%/zed/Makefile.am endif +if BUILD_MACOS +include $(srcdir)/%D%/zed/Makefile.am +include $(srcdir)/%D%/os/Makefile.am +endif if USING_PYTHON bin_SCRIPTS += arc_summary arcstat dbufstat zilstat @@ -111,6 +115,5 @@ arc_summary: %D%/arc_summary $(AM_V_at)cp $< $@ endif - PHONY += cmd cmd: $(bin_SCRIPTS) $(bin_PROGRAMS) $(sbin_SCRIPTS) $(sbin_PROGRAMS) $(dist_bin_SCRIPTS) $(zfsexec_PROGRAMS) $(mounthelper_PROGRAMS) diff --git a/cmd/arcstat.in b/cmd/arcstat.in index 8df1c62f7e86..6e46b6e233ac 100755 --- a/cmd/arcstat.in +++ b/cmd/arcstat.in @@ -220,7 +220,23 @@ elif sys.platform.startswith('linux'): name, unused, value = s.split() kstat[name] = int(value) +elif sys.platform.startswith('darwin'): + import subprocess + def kstat_update(): + global kstat + + process = subprocess.Popen(['sysctl', 'kstat.zfs.misc.arcstats'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + kstats = process.communicate()[0].decode('ascii').splitlines() + + kstat = {} + for l in kstats: + items = l.split(':') + name = items[0] + value = items[1].strip() + kstat[name[24:]] = int(value) def detailed_usage(): sys.stderr.write("%s\n" % cmd) diff --git a/cmd/os/Makefile.am b/cmd/os/Makefile.am new file mode 100644 index 000000000000..543ff7142808 --- /dev/null +++ b/cmd/os/Makefile.am @@ -0,0 +1,2 @@ + +include $(srcdir)/%D%/macos/Makefile.am diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 4b9921d47b81..5fd9aced777c 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -2189,16 +2189,16 @@ dump_history(spa_t *spa) if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) goto next; - (void) printf(" %s [internal %s txg:%ju] %s\n", + (void) printf(" %s [internal %s txg:%llu] %s\n", tbuf, zfs_history_event_names[ievent], - fnvlist_lookup_uint64(events[i], + (u_longlong_t)fnvlist_lookup_uint64(events[i], ZPOOL_HIST_TXG), fnvlist_lookup_string(events[i], ZPOOL_HIST_INT_STR)); } else if (nvlist_exists(events[i], ZPOOL_HIST_INT_NAME)) { - (void) printf("%s [txg:%ju] %s", tbuf, - fnvlist_lookup_uint64(events[i], + (void) printf("%s [txg:%llu] %s", tbuf, + (u_longlong_t)fnvlist_lookup_uint64(events[i], ZPOOL_HIST_TXG), fnvlist_lookup_string(events[i], ZPOOL_HIST_INT_NAME)); diff --git a/cmd/zed/Makefile.am b/cmd/zed/Makefile.am index c437ff51dd2b..11f906f59e50 100644 --- a/cmd/zed/Makefile.am +++ b/cmd/zed/Makefile.am @@ -40,7 +40,10 @@ zed_LDADD = \ libnvpair.la \ libuutil.la +if !BUILD_MACOS zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS) +endif + zed_LDFLAGS = -pthread dist_noinst_DATA += %D%/agents/README.md diff --git a/cmd/zed/agents/fmd_api.h b/cmd/zed/agents/fmd_api.h index b940d0d395ec..c0fa2d5f2efc 100644 --- a/cmd/zed/agents/fmd_api.h +++ b/cmd/zed/agents/fmd_api.h @@ -105,7 +105,7 @@ typedef struct fmd_stat { uint_t fmds_type; /* statistic type (see above) */ char fmds_desc[64]; /* statistic description */ union { - int bool; /* FMD_TYPE_BOOL */ + int fmds_bool; /* FMD_TYPE_BOOL */ int32_t i32; /* FMD_TYPE_INT32 */ uint32_t ui32; /* FMD_TYPE_UINT32 */ int64_t i64; /* FMD_TYPE_INT64 */ diff --git a/cmd/zed/zed.d/Makefile.am b/cmd/zed/zed.d/Makefile.am index c65b43fb027e..197fbbfeb384 100644 --- a/cmd/zed/zed.d/Makefile.am +++ b/cmd/zed/zed.d/Makefile.am @@ -14,11 +14,15 @@ dist_zedexec_SCRIPTS = \ %D%/resilver_finish-notify.sh \ %D%/resilver_finish-start-scrub.sh \ %D%/scrub_finish-notify.sh \ + %D%/snapshot_mount.sh \ + %D%/snapshot_unmount.sh \ %D%/statechange-led.sh \ %D%/statechange-notify.sh \ %D%/trim_finish-notify.sh \ %D%/vdev_attach-led.sh \ - %D%/vdev_clear-led.sh + %D%/vdev_clear-led.sh \ + %D%/zvol_create.sh \ + %D%/zvol_remove.sh nodist_zedexec_SCRIPTS = \ %D%/history_event-zfs-list-cacher.sh @@ -33,10 +37,14 @@ zedconfdefaults = \ resilver_finish-notify.sh \ resilver_finish-start-scrub.sh \ scrub_finish-notify.sh \ + snapshot_mount.sh \ + snapshot_unmount.sh \ statechange-led.sh \ statechange-notify.sh \ vdev_attach-led.sh \ - vdev_clear-led.sh + vdev_clear-led.sh \ + zvol_create.sh \ + zvol_remove.sh dist_noinst_DATA += %D%/README diff --git a/cmd/zed/zed.d/snapshot_mount.sh b/cmd/zed/zed.d/snapshot_mount.sh new file mode 100644 index 000000000000..111b692cea2f --- /dev/null +++ b/cmd/zed/zed.d/snapshot_mount.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Helper to mount and unmount snapshots when asked to by kernel. +# +# Mostly used in macOS. +# +set -ef + +[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc" +. "${ZED_ZEDLET_DIR}/zed-functions.sh" + +[ -n "${ZEVENT_SNAPSHOT_NAME}" ] || exit 1 +[ -n "${ZEVENT_SUBCLASS}" ] || exit 2 + +if [ "${ZEVENT_SUBCLASS}" = "snapshot_mount" ]; then + action="mount" +elif [ "${ZEVENT_SUBCLASS}" = "snapshot_unmount" ]; then + action="unmount" +else + zed_log_err "unsupported event class \"${ZEVENT_SUBCLASS}\"" + exit 3 +fi + +zed_exit_if_ignoring_this_event +zed_check_cmd "${ZFS}" || exit 4 + +"${ZFS}" "${action}" "${ZEVENT_SNAPSHOT_NAME}" + +finished diff --git a/cmd/zed/zed.d/snapshot_unmount.sh b/cmd/zed/zed.d/snapshot_unmount.sh new file mode 100644 index 000000000000..9f74a29e61f4 --- /dev/null +++ b/cmd/zed/zed.d/snapshot_unmount.sh @@ -0,0 +1 @@ +snapshot_mount.sh \ No newline at end of file diff --git a/cmd/zed/zed.d/zvol_create.sh b/cmd/zed/zed.d/zvol_create.sh new file mode 100644 index 000000000000..99f3370e3eab --- /dev/null +++ b/cmd/zed/zed.d/zvol_create.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Log the zevent via syslog. +# + +# Given POOL and DATASET name for ZVOL +# DEVICE_NAME for /dev/disk* +# RAW_DEVICE_NAME for /dev/rdisk* +# Create symlink in +# /var/run/zfs/zvol/dsk/POOL/DATASET -> /dev/disk* +# /var/run/zfs/zvol/rdsk/POOL/DATASET -> /dev/rdisk* + +ZVOL_ROOT="/var/run/zfs/zvol" + +mkdir -p "$(dirname "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" "$(dirname "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" + +# Remove them if they already exist. (ln -f is not portable) +rm -f "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" + +ln -s "/dev/${ZEVENT_DEVICE_NAME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" +ln -s "/dev/${ZEVENT_RAW_NAME}" "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" + +logger -t "${ZED_SYSLOG_TAG:=zed}" -p "${ZED_SYSLOG_PRIORITY:=daemon.notice}" \ + eid="${ZEVENT_EID}" class="${ZEVENT_SUBCLASS}" \ + "${ZEVENT_POOL:+pool=$ZEVENT_POOL}/${ZEVENT_VOLUME} symlinked ${ZEVENT_DEVICE_NAME}" + +echo 0 diff --git a/cmd/zed/zed.d/zvol_remove.sh b/cmd/zed/zed.d/zvol_remove.sh new file mode 100644 index 000000000000..1de53af38b68 --- /dev/null +++ b/cmd/zed/zed.d/zvol_remove.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Log the zevent via syslog. +# + +# Given POOL and DATASET name for ZVOL +# DEVICE_NAME for /dev/disk* +# RAW_DEVICE_NAME for /dev/rdisk* +# Create symlink in +# /var/run/zfs/zvol/dsk/POOL/DATASET -> /dev/disk* +# /var/run/zfs/zvol/rdsk/POOL/DATASET -> /dev/rdisk* + +ZVOL_ROOT="/var/run/zfs/zvol" + +rm -f "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" +rmdir "$(dirname "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" "$(dirname "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" + +logger -t "${ZED_SYSLOG_TAG:=zed}" -p "${ZED_SYSLOG_PRIORITY:=daemon.notice}" \ + eid="${ZEVENT_EID}" class="${ZEVENT_SUBCLASS}" \ + "${ZEVENT_POOL:+pool=$ZEVENT_POOL}/${ZEVENT_VOLUME} removed symlink" + +echo 0 diff --git a/cmd/zfs/Makefile.am b/cmd/zfs/Makefile.am index 8a3c13a1fcfe..eaf2530e5eea 100644 --- a/cmd/zfs/Makefile.am +++ b/cmd/zfs/Makefile.am @@ -20,3 +20,7 @@ zfs_LDADD += $(LTLIBINTL) if BUILD_FREEBSD zfs_LDADD += -lgeom -ljail endif + +if BUILD_MACOS +zfs_LDFLAGS = -sectcreate __TEXT __info_plist %D%/../zpool/os/macos/Info-zfs.plist +endif diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 5ed25d1ea720..0373162c91a2 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -784,7 +784,7 @@ zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type) } else if (zfs_share(zhp, NULL) != 0) { (void) fprintf(stderr, gettext("filesystem " "successfully created, but not shared\n")); - ret = 1; + ret = 0; } zfs_commit_shares(NULL); } @@ -1454,6 +1454,9 @@ destroy_callback(zfs_handle_t *zhp, void *data) if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { cb->cb_snap_count++; fnvlist_add_boolean(cb->cb_batchedsnaps, name); +#ifdef __APPLE__ + zfs_snapshot_unmount(zhp, cb->cb_force ? MS_FORCE : 0); +#endif if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy) { error = destroy_batched(cb); if (error != 0) { @@ -4178,6 +4181,11 @@ zfs_do_rollback(int argc, char **argv) */ ret = zfs_rollback(zhp, snap, force); +#ifdef __APPLE__ + if (ret == 0) + zfs_rollback_os(zhp); +#endif + out: zfs_close(snap); zfs_close(zhp); @@ -7266,6 +7274,39 @@ share_mount(int op, int argc, char **argv) (void) fclose(mnttab); } else { +#if defined(__APPLE__) + /* + * OsX can not mount from kernel, users are expected to mount + * by hand using "zfs mount dataset@snapshot". + */ + zfs_handle_t *zhp; + + if (argc > 1) { + (void) fprintf(stderr, + gettext("too many arguments\n")); + usage(B_FALSE); + } + + if ((zhp = zfs_open(g_zfs, argv[0], + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT)) == NULL) { + ret = 1; + } else { + + if (zfs_get_type(zhp)&ZFS_TYPE_SNAPSHOT) { + + ret = zfs_snapshot_mount(zhp, options, flags); + + } else { + + ret = share_mount_one(zhp, op, flags, + SA_NO_PROTOCOL, B_TRUE, options); + } + + zfs_close(zhp); + } + +#else // APPLE + zfs_handle_t *zhp; if (argc > 1) { @@ -7283,6 +7324,7 @@ share_mount(int op, int argc, char **argv) zfs_commit_shares(NULL); zfs_close(zhp); } +#endif // !APPLE } free(options); @@ -7654,9 +7696,23 @@ unshare_unmount(int op, int argc, char **argv) return (unshare_unmount_path(op, argv[0], flags, B_FALSE)); +#if defined(__APPLE__) + /* Temporarily, allow mounting snapshots on OS X */ + + if ((zhp = zfs_open(g_zfs, argv[0], + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT)) == NULL) + return (1); + + if (zfs_get_type(zhp) & ZFS_TYPE_SNAPSHOT) { + ret = zfs_snapshot_unmount(zhp, flags); + zfs_close(zhp); + return (ret); + } +#else if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM)) == NULL) return (1); +#endif verify(zfs_prop_get(zhp, op == OP_SHARE ? ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, diff --git a/cmd/zpool/Makefile.am b/cmd/zpool/Makefile.am index d08b8e1791b6..5e8a1959b0b8 100644 --- a/cmd/zpool/Makefile.am +++ b/cmd/zpool/Makefile.am @@ -24,6 +24,10 @@ zpool_SOURCES += \ %D%/os/linux/zpool_vdev_os.c endif +if BUILD_MACOS +zpool_SOURCES += %D%/os/macos/zpool_vdev_os.c +endif + zpool_LDADD = \ libzfs.la \ libzfs_core.la \ @@ -36,6 +40,12 @@ zpool_LDADD += $(LTLIBINTL) if BUILD_FREEBSD zpool_LDADD += -lgeom endif + +if BUILD_MACOS +zpool_LDFLAGS = -sectcreate __TEXT __info_plist %D%/os/macos/Info-zpool.plist +zpool_LDFLAGS += -sectcreate __TEXT __entitlements %D%/os/macos/zpool-entitlements.plist +endif + zpool_LDADD += -lm $(LIBBLKID_LIBS) $(LIBUUID_LIBS) dist_noinst_DATA += %D%/zpool.d/README diff --git a/cmd/zpool/zpool_vdev.c b/cmd/zpool/zpool_vdev.c index 99a521aa2a28..bd7879d0b8b6 100644 --- a/cmd/zpool/zpool_vdev.c +++ b/cmd/zpool/zpool_vdev.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -272,6 +273,9 @@ static nvlist_t * make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary) { char path[MAXPATHLEN]; + char *d, *b; + char *dpath; + const char *bname; struct stat64 statbuf; nvlist_t *vdev = NULL; const char *type = NULL; @@ -307,8 +311,29 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary) return (NULL); } - /* After whole disk check restore original passed path */ - strlcpy(path, arg, sizeof (path)); + /* + * After whole disk check restore original passed path and use + * the realpath of the directory. + */ + d = strdup(arg); + b = strdup(arg); + int idx = zfs_dirnamelen(d); + if (idx != -1) + d[idx] = 0; + dpath = d; + bname = zfs_basename(b); + if (realpath(dpath, path) == NULL) { + (void) fprintf(stderr, + gettext("cannot resolve path '%s'\n"), dpath); + free(d); + free(b); + return (NULL); + } + + strlcat(path, "/", sizeof (path)); + strlcat(path, bname, sizeof (path)); + free(d); + free(b); } else if (zpool_is_draid_spare(arg)) { if (!is_primary) { (void) fprintf(stderr, diff --git a/config/Rules.am b/config/Rules.am index abb4ced33233..63aea7c4c480 100644 --- a/config/Rules.am +++ b/config/Rules.am @@ -27,6 +27,10 @@ AM_CFLAGS += -fPIC -Werror -Wno-unknown-pragmas -Wno-enum-conversion AM_CFLAGS += -include $(top_srcdir)/include/os/freebsd/spl/sys/ccompile.h AM_CFLAGS += -I/usr/include -I/usr/local/include endif +if BUILD_MACOS +AM_CFLAGS += \ + -I$(top_srcdir)/lib/libspl/include/os/macos +endif AM_CPPFLAGS += -D_GNU_SOURCE AM_CPPFLAGS += -D_REENTRANT @@ -74,7 +78,6 @@ AM_LDFLAGS += -Wl,-x -Wl,--fatal-warnings -Wl,--warn-shared-textrel AM_LDFLAGS += -lm endif - # If a target includes kernel code, generate warnings for large stack frames KERNEL_CFLAGS = $(FRAME_LARGER_THAN) diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 index 6383b12506ee..d2689ee56ae8 100644 --- a/config/always-compiler-options.m4 +++ b/config/always-compiler-options.m4 @@ -355,3 +355,23 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_NO_IPA_SRA], [ CFLAGS="$saved_flags" AC_SUBST([KERNEL_NO_IPA_SRA]) ]) + +dnl # Check if cc supports -finline-hint-functions +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_INLINE_HINT_FUNCTIONS], [ + AC_MSG_CHECKING([whether $CC supports -finline-hint-functions]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -finline-hint-functions" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + INLINE_HINT_FUNCTIONS=-finline-hint-functions + AC_MSG_RESULT([yes]) + ], [ + INLINE_HINT_FUNCTIONS= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([INLINE_HINT_FUNCTIONS]) +]) diff --git a/config/always-system.m4 b/config/always-system.m4 index 3a3d4212f8b0..4bda7831e23d 100644 --- a/config/always-system.m4 +++ b/config/always-system.m4 @@ -16,6 +16,12 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SYSTEM], [ ac_system="FreeBSD" ac_system_l="freebsd" ;; + *darwin*) + AC_DEFINE([SYSTEM_MACOS], [1], + [True if ZFS is to be compiled for a macOS system]) + ac_system="macOS" + ac_system_l="macos" + ;; *) ac_system="unknown" ac_system_l="unknown" @@ -27,4 +33,5 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SYSTEM], [ AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"]) AM_CONDITIONAL([BUILD_FREEBSD], [test "x$ac_system" = "xFreeBSD"]) + AM_CONDITIONAL([BUILD_MACOS], [test "x$ac_system" = "xmacOS"]) ]) diff --git a/config/kernel-macos-headers.m4 b/config/kernel-macos-headers.m4 new file mode 100644 index 000000000000..0adbb9ba7133 --- /dev/null +++ b/config/kernel-macos-headers.m4 @@ -0,0 +1,103 @@ +dnl # +dnl # macOS - attempt to find kernel headers. This is expected to +dnl # only run on mac platforms (using xcrun command) to iterate +dnl # through versions of xcode, and xnu kernel source locations +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_MACOS_HEADERS], [ + AM_COND_IF([BUILD_MACOS], [ + AC_MSG_CHECKING([macOS kernel source directory]) + AS_IF([test -z "$kernelsrc"], [ + system_major_version=`sw_vers -productVersion | $AWK -F '.' '{ print $[]1 "." $[]2 }'` + AS_IF([test -d "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${system_major_version}.sdk/System/Library/Frameworks/Kernel.framework/Headers"], [ + kernelsrc="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${system_major_version}.sdk/System/Library/Frameworks/Kernel.framework"]) + ]) + AS_IF([test -z "$kernelsrc"], [ + AS_IF([test -d "/System/Library/Frameworks/Kernel.framework/Headers"], [ + kernelsrc="/System/Library/Frameworks/Kernel.framework"]) + ]) + AS_IF([test -z "$kernelsrc"], [ + tmpdir=`xcrun --show-sdk-path` + AS_IF([test -d "$tmpdir/System/Library/Frameworks/Kernel.framework/Headers"], [ + kernelsrc="$tmpdir/System/Library/Frameworks/Kernel.framework"]) + ]) + AS_IF([test -z "$kernelsrc"], [ + AS_IF([test -d "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/Kernel.framework"], [ + kernelsrc="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/Kernel.framework"]) + ]) + AS_IF([test -z "$kernelsrc"], [ + AS_IF([test -d "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Kernel.framework"], [ + kernelsrc="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Kernel.framework"]) + ]) + AS_IF([test -z "$kernelsrc"], [ + AS_IF([test -d "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Kernel.framework"], [ + kernelsrc="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Kernel.framework"]) + ]) + + AC_MSG_RESULT([$kernelsrc]) + + AC_MSG_CHECKING([macOS kernel build directory]) + AS_IF([test -z "$kernelbuild"], [ + kernelbuild=${kernelsrc} + ]) + ]) + AC_MSG_RESULT([$kernelbuild]) + + AC_ARG_WITH([kernel-modprefix], + AS_HELP_STRING([--with-kernel-modprefix=PATH], + [Path to kernel module prefix]), + [KERNEL_MODPREFIX="$withval"]) + AC_MSG_CHECKING([macOS kernel module prefix]) + AS_IF([test -z "$KERNEL_MODPREFIX"], [ + KERNEL_MODPREFIX="/Library/Extensions" + ]) + AC_MSG_RESULT([$KERNEL_MODPREFIX]) + AC_DEFINE_UNQUOTED([KERNEL_MODPREFIX], + ["$KERNEL_MODPREFIX"], + [Path where the kernel module is installed.] + ) + + AC_MSG_CHECKING([macOS kernel source version]) + utsrelease1=$kernelbuild/Headers/libkern/version.h + AS_IF([test -r $utsrelease1 && fgrep -q OSRELEASE $utsrelease1], [ + kernverfile=libkern/version.h ]) + + AS_IF([test "$kernverfile"], [ + kernsrcver=`(echo "#include <$kernverfile>"; + echo "kernsrcver=OSRELEASE") | + cpp -I$kernelbuild/Headers | + grep "^kernsrcver=" | cut -d \" -f 2` + + AS_IF([test -z "$kernsrcver"], [ + AC_MSG_RESULT([Not found]) + AC_MSG_ERROR([*** Cannot determine kernel version.]) + ]) + AC_MSG_RESULT([$kernsrcver]) + ]) + + AC_MSG_CHECKING([mach_kernel]) + AS_IF([test -z "$machkernel"], [ + AS_IF([test -e "/System/Library/Kernels/kernel"], [ + machkernel="/System/Library/Kernels/kernel" ] ) + AS_IF([test -e "/mach_kernel"], [ + machkernel="/mach_kernel" ] ) + AS_IF([test ! -f "$machkernel"], [ + AC_MSG_ERROR([ + *** mach_kernel file not found. For 10.9 and prior, this should be + *** '/mach_kernel' and for 10.10 and following, this should be + *** '/System/Library/Kernels/kernel']) + ]) + ]) + AC_MSG_RESULT($machkernel) + + +dnl More Generic names: + MACH_KERNEL=${machkernel} + KERNEL_HEADERS=${kernelsrc} + KERNEL_VERSION=${kernsrcver} + AC_SUBST(KERNEL_HEADERS) + AC_SUBST(KERNEL_MODPREFIX) + AC_SUBST(KERNEL_VERSION) + AC_SUBST(MACH_KERNEL) + ]) +]) + diff --git a/config/kernel.m4 b/config/kernel.m4 index df194ec72207..76c36ebabee3 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -28,6 +28,10 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ AC_SUBST(KERNEL_MAKE) ]) + AM_COND_IF([BUILD_MACOS], [ + ZFS_AC_KERNEL_SRC_MACOS_HEADERS + ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN + ]) ]) dnl # @@ -372,6 +376,7 @@ dnl # and `/usr/src/linux-*` with the highest version number according dnl # to `sort -V` is assumed to be both source and build directory. dnl # AC_DEFUN([ZFS_AC_KERNEL], [ + AC_ARG_WITH([linux], AS_HELP_STRING([--with-linux=PATH], [Path to kernel source]), @@ -382,6 +387,15 @@ AC_DEFUN([ZFS_AC_KERNEL], [ [Path to kernel build objects]), [kernelbuild="$withval"]) + AC_ARG_WITH([macos], + AS_HELP_STRING([--with-macos=PATH], + [Path to macOS source]), + [kernelsrc="$withval/sys"]) + AC_ARG_WITH(macos-obj, + AS_HELP_STRING([--with-macos-obj=PATH], + [Path to macOS build objects]), + [kernelbuild="$withval/$kernelsrc"]) + AC_MSG_CHECKING([kernel source and build directories]) AS_IF([test -n "$kernelsrc" && test -z "$kernelbuild"], [ kernelbuild="$kernelsrc" @@ -445,7 +459,8 @@ AC_DEFUN([ZFS_AC_KERNEL], [ *** Please make sure the kernel devel package for your distribution *** is installed and then try again. If that fails, you can specify the *** location of the kernel source and build with the '--with-linux=PATH' and - *** '--with-linux-obj=PATH' options respectively.]) + *** '--with-linux-obj=PATH' options respectively. + *** If you are configuring for macOS, use '--with-macos=PATH'.]) ]) AC_MSG_CHECKING([kernel source version]) @@ -596,9 +611,9 @@ dnl # ZFS_LINUX_CONFTEST_H dnl # AC_DEFUN([ZFS_LINUX_CONFTEST_H], [ test -d build/$2 || mkdir -p build/$2 -cat - <<_ACEOF >build/$2/$2.h +cat - <<_ACEOF1 >build/$2/$2.h $1 -_ACEOF +_ACEOF1 ]) dnl # @@ -606,9 +621,9 @@ dnl # ZFS_LINUX_CONFTEST_C dnl # AC_DEFUN([ZFS_LINUX_CONFTEST_C], [ test -d build/$2 || mkdir -p build/$2 -cat confdefs.h - <<_ACEOF >build/$2/$2.c +cat confdefs.h - <<_ACEOF2 >build/$2/$2.c $1 -_ACEOF +_ACEOF2 ]) dnl # @@ -625,12 +640,12 @@ AC_DEFUN([ZFS_LINUX_CONFTEST_MAKEFILE], [ file=build/$1/Makefile dnl # Example command line to manually build source. - cat - <<_ACEOF >$file + cat - <<_ACEOF3 >$file # Example command line to manually build source # make modules -C $LINUX_OBJ $ARCH_UM M=$PWD/build/$1 ccflags-y := -Werror $FRAME_LARGER_THAN -_ACEOF +_ACEOF3 dnl # Additional custom CFLAGS as requested. m4_ifval($3, [echo "ccflags-y += $3" >>$file], []) diff --git a/config/macos.m4 b/config/macos.m4 new file mode 100644 index 000000000000..30e8ebf2ec46 --- /dev/null +++ b/config/macos.m4 @@ -0,0 +1,11 @@ + + +AC_DEFUN([ZFS_AC_MACOS_IMPURE_ENABLE], [ + AC_ARG_ENABLE(macos_impure, + AS_HELP_STRING([--enable-macos-impure], + [Use XNU Private.exports [[default: no]]]), + [CPPFLAGS="$CPPFLAGS -DMACOS_IMPURE"], + []) +]) + + diff --git a/config/user-libfetch.m4 b/config/user-libfetch.m4 index d961c6ca77a1..0b727e43dd66 100644 --- a/config/user-libfetch.m4 +++ b/config/user-libfetch.m4 @@ -45,8 +45,14 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBFETCH], [ LIBFETCH_IS_LIBCURL=1 if test "$(curl-config --built-shared)" = "yes"; then LIBFETCH_DYNAMIC=1 - LIBFETCH_SONAME="libcurl.so.4" - LIBFETCH_LIBS="-ldl" + dnl # why are we hardcoding libnames? + AM_COND_IF([BUILD_MACOS], [ + LIBFETCH_SONAME="libcurl.4.dylib" + LIBFETCH_LIBS="" + ], [ + LIBFETCH_SONAME="libcurl.so.4" + LIBFETCH_LIBS="-ldl" + ]) AC_MSG_RESULT([libcurl]) else LIBFETCH_LIBS="$(curl-config --libs)" diff --git a/config/user.m4 b/config/user.m4 index 6ec27a5b2cf5..6a97a21bbecf 100644 --- a/config/user.m4 +++ b/config/user.m4 @@ -24,8 +24,11 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_LIBATOMIC ZFS_AC_CONFIG_USER_LIBFETCH ZFS_AC_CONFIG_USER_AIO_H - ZFS_AC_CONFIG_USER_CLOCK_GETTIME - ZFS_AC_CONFIG_USER_PAM + AM_COND_IF([BUILD_MACOS], [ + ZFS_AC_MACOS_IMPURE_ENABLE], [ + ZFS_AC_CONFIG_USER_CLOCK_GETTIME + ZFS_AC_CONFIG_USER_PAM + ]) ZFS_AC_CONFIG_USER_RUNSTATEDIR ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index 2703e6c016c4..d62c1f95255d 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -535,6 +535,8 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ VENDOR=freebsd ; elif test -f /etc/openEuler-release ; then VENDOR=openeuler ; + elif test -f /usr/bin/sw_vers ; then + VENDOR=apple ; else VENDOR= ; fi], @@ -560,6 +562,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ debian) DEFAULT_PACKAGE=deb ;; freebsd) DEFAULT_PACKAGE=pkg ;; openeuler) DEFAULT_PACKAGE=rpm ;; + apple) DEFAULT_PACKAGE=pkg ;; *) DEFAULT_PACKAGE=rpm ;; esac AC_MSG_RESULT([$DEFAULT_PACKAGE]) @@ -603,6 +606,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ ubuntu) initconfdir=/etc/default ;; debian) initconfdir=/etc/default ;; freebsd) initconfdir=$sysconfdir/rc.conf.d;; + apple) initconfdir=${prefix}/etc/launchd/launchd.d/ ;; *) initconfdir=/etc/default ;; esac AC_MSG_RESULT([$initconfdir]) @@ -624,7 +628,7 @@ dnl # Default ZFS package configuration dnl # AC_DEFUN([ZFS_AC_PACKAGE], [ ZFS_AC_DEFAULT_PACKAGE - AS_IF([test x$VENDOR != xfreebsd], [ + AS_IF([test x$VENDOR != xfreebsd -a x$VENDOR != xapple], [ ZFS_AC_RPM ZFS_AC_DPKG ZFS_AC_ALIEN diff --git a/configure.ac b/configure.ac index 4c75616e4299..403c2762a675 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,7 @@ AM_INIT_AUTOMAKE([subdir-objects foreign]) # Remove default macros from config.h: # PACKAGE, PACKAGE_{BUGREPORT,NAME,STRING,TARNAME,VERSION}, STDC_HEADERS, VERSION AC_CONFIG_HEADERS([zfs_config.h], [ - sed -nri~ -e '/^$/be' -e 'N;N;/#define (PACKAGE|VERSION|STDC_HEADERS)/d' -e ':e' -e 'p' zfs_config.h && rm zfs_config.h~ || exit]) + $SED -nri~ -e '/^$/be' -e 'N;N;/#define (PACKAGE|VERSION|STDC_HEADERS)/d' -e ':e' -e 'p' zfs_config.h && rm zfs_config.h~ || exit]) LT_INIT AC_PROG_INSTALL @@ -55,6 +55,9 @@ AM_PROG_AS AM_PROG_CC_C_O AX_CODE_COVERAGE _AM_PROG_TAR(pax) +AC_PROG_CXX(clang++) +AC_PROG_OBJC(clang) +AC_PROG_OBJCXX(clang++) ZFS_AC_LICENSE ZFS_AC_CONFIG diff --git a/etc/Makefile.am b/etc/Makefile.am index 7187762d3802..3121ebf2680b 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -97,3 +97,9 @@ dist_modulesload_DATA = \ %D%/modules-load.d/zfs.conf endif endif + +if BUILD_MACOS +include $(srcdir)/%D%/launchd/Makefile.am +include $(srcdir)/%D%/paths.d/Makefile.am +include $(srcdir)/%D%/launchd.d/Makefile.am +endif diff --git a/etc/paths.d/.gitignore b/etc/paths.d/.gitignore new file mode 100644 index 000000000000..f916e9fbee04 --- /dev/null +++ b/etc/paths.d/.gitignore @@ -0,0 +1 @@ +zfs-path diff --git a/etc/paths.d/Makefile.am b/etc/paths.d/Makefile.am new file mode 100644 index 000000000000..8b7f5998b926 --- /dev/null +++ b/etc/paths.d/Makefile.am @@ -0,0 +1,20 @@ +pathsddir = $(sysconfdir)/paths.d +pathsd_DATA = %D%/zfs-path + +paths_ddir = $(sysconfdir)/paths.d/ +dist_paths_d_DATA = \ + %D%/zfs-path + +zfs-path: %D%/zfs-path.in + +CLEANFILES += $(pathsd_DATA) +CLEANFILES += %D%/zfs-path +INSTALL_DATA_HOOKS += pathsd-data-hook +pathsd-data-hook: %D%/zfs-path.in + -$(SED) -e 's,@bindir\@,$(bindir),g' \ + -e 's,@runstatedir\@,$(runstatedir),g' \ + -e 's,@sbindir\@,$(sbindir),g' \ + -e 's,@sysconfdir\@,$(sysconfdir),g' \ + -e 's,@launchddaemondir\@,$(launchddaemondir),g' \ + -e 's,@launchdscriptdir\@,$(launchdscriptdir),g' \ + %D%/zfs-path.in > $(DESTDIR)/$(sysconfdir)/paths.d/zfs-path diff --git a/etc/paths.d/zfs-path.in b/etc/paths.d/zfs-path.in new file mode 100644 index 000000000000..5532f40754b3 --- /dev/null +++ b/etc/paths.d/zfs-path.in @@ -0,0 +1,2 @@ +@bindir@ +@sbindir@ diff --git a/include/libzfs.h b/include/libzfs.h index a7037e3e6266..20803f7cb889 100644 --- a/include/libzfs.h +++ b/include/libzfs.h @@ -985,6 +985,7 @@ _LIBZFS_H int zpool_enable_datasets(zpool_handle_t *, const char *, int); _LIBZFS_H int zpool_disable_datasets(zpool_handle_t *, boolean_t); _LIBZFS_H void zpool_disable_datasets_os(zpool_handle_t *, boolean_t); _LIBZFS_H void zpool_disable_volume_os(const char *); +_LIBZFS_H void zfs_rollback_os(struct zfs_handle *); /* * Parse a features file for -o compatibility @@ -1021,9 +1022,25 @@ _LIBZFS_H int zpool_nextboot(libzfs_handle_t *, uint64_t, uint64_t, * Add or delete the given filesystem to/from the given user namespace. */ _LIBZFS_H int zfs_userns(zfs_handle_t *zhp, const char *nspath, int attach); +#endif +#ifdef __APPLE__ +_LIBZFS_H int zfs_snapshot_mount(zfs_handle_t *, const char *, int); +_LIBZFS_H int zfs_snapshot_unmount(zfs_handle_t *, int); +/* We moved these from libspl to libzfs to be able to do more */ +_LIBZFS_H int getmntent(FILE *, struct mnttab *); +_LIBZFS_H char *hasmntopt(struct mnttab *, const char *); +_LIBZFS_H int getextmntent(const char *, struct extmnttab *, + struct stat64 *); +_LIBZFS_H int do_mount(zfs_handle_t *, const char *, const char *, int); #endif +/* + * Manual mounting of snapshots. + */ +extern int zfs_snapshot_mount(zfs_handle_t *, const char *, int); +extern int zfs_snapshot_unmount(zfs_handle_t *, int); + #ifdef __cplusplus } #endif diff --git a/include/libzutil.h b/include/libzutil.h index 237ff976ba62..f66126fe7665 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -109,7 +109,11 @@ _LIBZUTIL_H void update_vdev_config_dev_strs(nvlist_t *); * Default device paths */ #define DISK_ROOT "/dev" +#ifdef __APPLE__ +#define UDISK_ROOT "/private/var/run/disk" +#else #define UDISK_ROOT "/dev/disk" +#endif #define ZVOL_ROOT "/dev/zvol" _LIBZUTIL_H int zfs_append_partition(char *path, size_t max_len); @@ -193,6 +197,9 @@ _LIBZUTIL_H ssize_t zfs_dirnamelen(const char *path); extern char **environ; _LIBZUTIL_H void zfs_setproctitle_init(int argc, char *argv[], char *envp[]); _LIBZUTIL_H void zfs_setproctitle(const char *fmt, ...); +#elif defined(__APPLE__) +#define zfs_setproctitle(fmt, ...) setproctitle(fmt, ##__VA_ARGS__) +#define zfs_setproctitle_init(x, y, z) ((void)0) #else #define zfs_setproctitle(fmt, ...) setproctitle(fmt, ##__VA_ARGS__) #define zfs_setproctitle_init(x, y, z) ((void)0) diff --git a/include/os/freebsd/spl/sys/simd_aarch64.h b/include/os/freebsd/spl/sys/simd_aarch64.h index 234f401db791..2af01a939afb 100644 --- a/include/os/freebsd/spl/sys/simd_aarch64.h +++ b/include/os/freebsd/spl/sys/simd_aarch64.h @@ -91,4 +91,13 @@ zfs_sha512_available(void) return (elf_hwcap & HWCAP_SHA512); } +/* + * Check if AESV8 is available + */ +static inline boolean_t +zfs_aesv8_available(void) +{ + return (elf_hwcap & HWCAP_AES); +} + #endif /* _FREEBSD_SIMD_AARCH64_H */ diff --git a/include/os/linux/kernel/linux/simd_aarch64.h b/include/os/linux/kernel/linux/simd_aarch64.h index 16276b08c759..e48c9b3be932 100644 --- a/include/os/linux/kernel/linux/simd_aarch64.h +++ b/include/os/linux/kernel/linux/simd_aarch64.h @@ -113,4 +113,14 @@ zfs_sha512_available(void) return (ftr & 0x2); } +/* + * Check if AESV8 is available + */ +static inline boolean_t +zfs_aesv8_available(void) +{ + unsigned long ftr = ((get_ftr(ID_AA64ISAR0_EL1)) >> 4) & 0x3; + return (ftr); +} + #endif /* _LINUX_SIMD_AARCH64_H */ diff --git a/include/os/linux/zfs/sys/zfs_context_os.h b/include/os/linux/zfs/sys/zfs_context_os.h index 04a5f0c0d239..ca424785b975 100644 --- a/include/os/linux/zfs/sys/zfs_context_os.h +++ b/include/os/linux/zfs/sys/zfs_context_os.h @@ -37,4 +37,8 @@ #undef longjmp #endif +#ifndef MODULE_PARAM_MAX +#define MODULE_PARAM_MAX 1024 +#endif + #endif diff --git a/include/sys/abd.h b/include/sys/abd.h index 750f9986c1da..08c1c9ce5760 100644 --- a/include/sys/abd.h +++ b/include/sys/abd.h @@ -60,7 +60,8 @@ typedef struct abd { union { struct abd_scatter { uint_t abd_offset; -#if defined(__FreeBSD__) && defined(_KERNEL) +#if defined(_KERNEL) && (defined(__FreeBSD__) || defined(__APPLE__)) + uint_t abd_chunk_size; void *abd_chunks[1]; /* actually variable-length */ #else uint_t abd_nents; @@ -129,6 +130,7 @@ void abd_copy_off(abd_t *, abd_t *, size_t, size_t, size_t); void abd_copy_from_buf_off(abd_t *, const void *, size_t, size_t); void abd_copy_to_buf_off(void *, abd_t *, size_t, size_t); int abd_cmp(abd_t *, abd_t *); +int abd_cmp_size(abd_t *, abd_t *, size_t); int abd_cmp_buf_off(abd_t *, const void *, size_t, size_t); void abd_zero_off(abd_t *, size_t, size_t); void abd_verify(abd_t *); @@ -176,6 +178,11 @@ abd_zero(abd_t *abd, size_t size) abd_zero_off(abd, 0, size); } +#ifdef __APPLE__ +void abd_return_buf_off(abd_t *, void *, size_t, size_t, size_t); +void abd_return_buf_copy_off(abd_t *, void *, size_t, size_t, size_t); +#endif + /* * ABD type check functions */ diff --git a/include/sys/abd_impl.h b/include/sys/abd_impl.h index 40546d4af137..6d7b4ccc3a59 100644 --- a/include/sys/abd_impl.h +++ b/include/sys/abd_impl.h @@ -95,6 +95,9 @@ void abd_iter_unmap(struct abd_iter *); #if defined(__FreeBSD__) #define abd_enter_critical(flags) critical_enter() #define abd_exit_critical(flags) critical_exit() +#elif defined(__APPLE__) +#define abd_enter_critical(flags) (flags) = ml_set_interrupts_enabled(FALSE) +#define abd_exit_critical(flags) ml_set_interrupts_enabled((flags)) #else #define abd_enter_critical(flags) local_irq_save(flags) #define abd_exit_critical(flags) local_irq_restore(flags) diff --git a/include/sys/asm_linkage.h b/include/sys/asm_linkage.h index 749157d4c3db..95958ad918ae 100644 --- a/include/sys/asm_linkage.h +++ b/include/sys/asm_linkage.h @@ -33,6 +33,10 @@ #include /* XX64 x86/sys/asm_linkage.h */ +#elif defined(__aarch64__) + +#include + #endif #if defined(_KERNEL) && defined(HAVE_KERNEL_OBJTOOL) diff --git a/include/sys/crypto/icp.h b/include/sys/crypto/icp.h index 8c3f19886fd8..fca3f8194546 100644 --- a/include/sys/crypto/icp.h +++ b/include/sys/crypto/icp.h @@ -39,6 +39,9 @@ int icp_init(void); void icp_fini(void); int aes_impl_set(const char *); +int aes_impl_get(char *, size_t); int gcm_impl_set(const char *); +int gcm_impl_get(char *, size_t); + #endif /* _SYS_CRYPTO_ALGS_H */ diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index bc940e8a7929..216f0af96a9b 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -191,6 +191,11 @@ typedef enum { ZFS_PROP_REDACTED, ZFS_PROP_REDACT_SNAPS, ZFS_PROP_SNAPSHOTS_CHANGED, + ZFS_PROP_BROWSE, /* macOS: nobrowse/browse */ + ZFS_PROP_IGNOREOWNER, /* macOS: ignoreowner mount */ + ZFS_PROP_LASTUNMOUNT, /* macOS: Spotlight required */ + ZFS_PROP_MIMIC, /* macOS: mimic=hfs|apfs */ + ZFS_PROP_DEVDISK, /* macOS: create IOkit virtual disk */ ZFS_NUM_PROPS } zfs_prop_t; @@ -543,6 +548,18 @@ typedef enum zfs_key_location { ZFS_KEYLOCATION_LOCATIONS } zfs_keylocation_t; +typedef enum zfs_mimic { + ZFS_MIMIC_OFF = 0, + ZFS_MIMIC_HFS, + ZFS_MIMIC_APFS +} zfs_mimic_t; + +typedef enum zfs_devdisk { + ZFS_DEVDISK_POOLONLY = 0, + ZFS_DEVDISK_OFF, + ZFS_DEVDISK_ON +} zfs_devdisk_t; + #define DEFAULT_PBKDF2_ITERATIONS 350000 #define MIN_PBKDF2_ITERATIONS 100000 @@ -1379,7 +1396,7 @@ typedef enum zfs_ioc { /* * Core features - 88/128 numbers reserved. */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__APPLE__) ZFS_IOC_FIRST = 0, #else ZFS_IOC_FIRST = ('Z' << 8), @@ -1488,6 +1505,8 @@ typedef enum zfs_ioc { ZFS_IOC_USERNS_DETACH = ZFS_IOC_UNJAIL, /* 0x86 (Linux) */ ZFS_IOC_SET_BOOTENV, /* 0x87 */ ZFS_IOC_GET_BOOTENV, /* 0x88 */ + ZFS_IOC_PROXY_DATASET, /* 0x89 (macOS) */ + ZFS_IOC_PROXY_REMOVE, /* 0x8a (macOS) */ ZFS_IOC_LAST } zfs_ioc_t; diff --git a/include/sys/mntent.h b/include/sys/mntent.h index 5bb7e080cda8..4449ea1206a8 100644 --- a/include/sys/mntent.h +++ b/include/sys/mntent.h @@ -79,6 +79,13 @@ #elif defined(__FreeBSD__) #define MNTOPT_SETUID "setuid" /* Set uid allowed */ #define MNTOPT_NOSETUID "nosetuid" /* Set uid not allowed */ +#elif defined(__APPLE__) +#define MNTOPT_SETUID "setuid" /* Set uid allowed */ +#define MNTOPT_NOSETUID "nosetuid" /* Set uid not allowed */ +#define MNTOPT_BROWSE "browse" /* browsable autofs mount */ +#define MNTOPT_NOBROWSE "nobrowse" /* non-browsable autofs mount */ +#define MNTOPT_OWNERS "owners" /* use ownership */ +#define MNTOPT_NOOWNERS "noowners" /* ignore ownership */ #else #error "unknown OS" #endif diff --git a/include/sys/spa.h b/include/sys/spa.h index b90855687411..09fe4a40ccf0 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -1142,6 +1142,8 @@ extern boolean_t zfs_ereport_is_valid(const char *clazz, spa_t *spa, vdev_t *vd, zio_t *zio); extern void zfs_ereport_taskq_fini(void); extern void zfs_ereport_clear(spa_t *spa, vdev_t *vd); +extern void zfs_ereport_zvol_post(const char *subclass, const char *name, + const char *bsd, const char *rbsd); extern nvlist_t *zfs_event_create(spa_t *spa, vdev_t *vd, const char *type, const char *name, nvlist_t *aux); extern void zfs_post_remove(spa_t *spa, vdev_t *vd); diff --git a/include/sys/spa_impl.h b/include/sys/spa_impl.h index 588c72f6e4fa..f53bd6517d3d 100644 --- a/include/sys/spa_impl.h +++ b/include/sys/spa_impl.h @@ -438,6 +438,9 @@ struct spa { boolean_t spa_waiters_cancel; /* waiters should return */ char *spa_compatibility; /* compatibility file(s) */ +#ifdef __APPLE__ + spa_iokit_t *spa_iokit_proxy; /* IOKit pool proxy */ +#endif /* * spa_refcount & spa_config_lock must be the last elements diff --git a/include/sys/sysevent/dev.h b/include/sys/sysevent/dev.h index 0783d0073162..d0eb96eb6b17 100644 --- a/include/sys/sysevent/dev.h +++ b/include/sys/sysevent/dev.h @@ -239,7 +239,7 @@ extern "C" { #define DEV_INSTANCE "instance" #define DEV_PROP_PREFIX "prop-" -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #define DEV_IDENTIFIER "devid" #define DEV_PATH "path" #define DEV_IS_PART "is_slice" diff --git a/include/sys/vdev_raidz.h b/include/sys/vdev_raidz.h index e34b6e4b158e..f8fc4bacbdc0 100644 --- a/include/sys/vdev_raidz.h +++ b/include/sys/vdev_raidz.h @@ -64,6 +64,7 @@ int vdev_raidz_math_generate(struct raidz_map *, struct raidz_row *); int vdev_raidz_math_reconstruct(struct raidz_map *, struct raidz_row *, const int *, const int *, const int); int vdev_raidz_impl_set(const char *); +int vdev_raidz_impl_get(char *buffer, size_t max); typedef struct vdev_raidz { int vd_logical_width; diff --git a/include/sys/xvattr.h b/include/sys/xvattr.h index a7994db894b9..53d02d3b584d 100644 --- a/include/sys/xvattr.h +++ b/include/sys/xvattr.h @@ -67,6 +67,9 @@ typedef struct xoptattr { uint8_t xoa_sparse; uint8_t xoa_projinherit; uint64_t xoa_projid; + uint8_t xoa_tracked; /* macOS */; + uint8_t xoa_sappendonly; /* macOS */; + uint8_t xoa_simmutable; /* macOS */; } xoptattr_t; /* @@ -174,12 +177,16 @@ typedef struct xvattr { #define XAT0_SPARSE 0x00010000 /* sparse */ #define XAT0_PROJINHERIT 0x00020000 /* Create with parent projid */ #define XAT0_PROJID 0x00040000 /* Project ID */ +#define XAT0_TRACKED 0x00080000 /* macOS UF_TRACKED */ +#define XAT0_SAPPENDONLY 0x00100000 /* macOS SF_APPENDONLY */ +#define XAT0_SIMMUTABLE 0x00200000 /* macOS SF_IMMUTABLE */ #define XAT0_ALL_ATTRS (XAT0_CREATETIME|XAT0_ARCHIVE|XAT0_SYSTEM| \ XAT0_READONLY|XAT0_HIDDEN|XAT0_NOUNLINK|XAT0_IMMUTABLE|XAT0_APPENDONLY| \ XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED| XAT0_AV_MODIFIED| \ XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE| \ - XAT0_PROJINHERIT | XAT0_PROJID) + XAT0_PROJINHERIT | XAT0_PROJID|XAT0_TRACKED|XAT0_SAPPENDONLY| \ + XAT0_SIMMUTABLE) /* Support for XAT_* optional attributes */ #define XVA_MASK 0xffffffff /* Used to mask off 32 bits */ @@ -218,6 +225,9 @@ typedef struct xvattr { #define XAT_SPARSE ((XAT0_INDEX << XVA_SHFT) | XAT0_SPARSE) #define XAT_PROJINHERIT ((XAT0_INDEX << XVA_SHFT) | XAT0_PROJINHERIT) #define XAT_PROJID ((XAT0_INDEX << XVA_SHFT) | XAT0_PROJID) +#define XAT_TRACKED ((XAT0_INDEX << XVA_SHFT) | XAT0_TRACKED) +#define XAT_SAPPENDONLY ((XAT0_INDEX << XVA_SHFT) | XAT0_SAPPENDONLY) +#define XAT_SIMMUTABLE ((XAT0_INDEX << XVA_SHFT) | XAT0_SIMMUTABLE) /* * The returned attribute map array (xva_rtnattrmap[]) is located past the diff --git a/include/sys/zfs_bootenv.h b/include/sys/zfs_bootenv.h index 7af0a57dd008..5823da980b48 100644 --- a/include/sys/zfs_bootenv.h +++ b/include/sys/zfs_bootenv.h @@ -30,6 +30,7 @@ extern "C" { #define BE_FREEBSD_VENDOR "freebsd" #define BE_GRUB_VENDOR "grub" #define BE_LINUX_VENDOR "linux" +#define BE_MACOS_VENDOR "macos" #include diff --git a/include/sys/zfs_debug.h b/include/sys/zfs_debug.h index a1dfef1d89ff..b4fad7ffa6e2 100644 --- a/include/sys/zfs_debug.h +++ b/include/sys/zfs_debug.h @@ -83,12 +83,27 @@ extern void __dprintf(boolean_t dprint, const char *file, const char *func, if (zfs_dbgmsg_enable) \ __dprintf(B_FALSE, __FILE__, __func__, __LINE__, __VA_ARGS__) -#ifdef ZFS_DEBUG +#ifdef __APPLE__ /* * To enable this: * - * $ echo 1 >/sys/module/zfs/parameters/zfs_flags + * $ sysctl kstat.zfs.darwin.tunable.zfs_flags=1 */ +#ifdef _KERNEL +#undef dprintf +#define dprintf(...) \ + if (zfs_flags & ZFS_DEBUG_DPRINTF) \ + __dprintf(B_TRUE, __FILE__, __func__, __LINE__, __VA_ARGS__) +#endif + +#else /* !APPLE */ + +#ifdef ZFS_DEBUG + /* + * To enable this: + * + * $ echo 1 >/sys/module/zfs/parameters/zfs_flags + */ #define dprintf(...) \ if (zfs_flags & ZFS_DEBUG_DPRINTF) \ __dprintf(B_TRUE, __FILE__, __func__, __LINE__, __VA_ARGS__) @@ -96,6 +111,8 @@ extern void __dprintf(boolean_t dprint, const char *file, const char *func, #define dprintf(...) ((void)0) #endif /* ZFS_DEBUG */ +#endif /* !APPLE */ + extern void zfs_panic_recover(const char *fmt, ...); extern void zfs_dbgmsg_init(void); diff --git a/include/sys/zfs_file.h b/include/sys/zfs_file.h index e944165adc40..c11ba376ded4 100644 --- a/include/sys/zfs_file.h +++ b/include/sys/zfs_file.h @@ -31,6 +31,8 @@ typedef struct zfs_file { } zfs_file_t; #elif defined(__linux__) || defined(__FreeBSD__) typedef struct file zfs_file_t; +#elif defined(__APPLE__) +typedef struct spl_fileproc zfs_file_t; #else #error "unknown OS" #endif diff --git a/include/sys/zfs_ioctl_impl.h b/include/sys/zfs_ioctl_impl.h index cb852c5577fd..df5fe41bae43 100644 --- a/include/sys/zfs_ioctl_impl.h +++ b/include/sys/zfs_ioctl_impl.h @@ -75,6 +75,9 @@ int zfs_secpolicy_config(zfs_cmd_t *, nvlist_t *, cred_t *); void zfs_ioctl_register_dataset_nolog(zfs_ioc_t, zfs_ioc_legacy_func_t *, zfs_secpolicy_func_t *, zfs_ioc_poolcheck_t); +void zfs_ioctl_register_pool(zfs_ioc_t, zfs_ioc_legacy_func_t *, + zfs_secpolicy_func_t *, boolean_t, zfs_ioc_poolcheck_t); + void zfs_ioctl_register(const char *, zfs_ioc_t, zfs_ioc_func_t *, zfs_secpolicy_func_t *, zfs_ioc_namecheck_t, zfs_ioc_poolcheck_t, diff --git a/include/sys/zfs_sa.h b/include/sys/zfs_sa.h index 1b4b8abf0244..502d3e8f35a2 100644 --- a/include/sys/zfs_sa.h +++ b/include/sys/zfs_sa.h @@ -75,6 +75,16 @@ typedef enum zpl_attr { ZPL_DACL_ACES, ZPL_DXATTR, ZPL_PROJID, + + /* + * Apple defines a ADDEDTIME, which is the time the entry was placed + * in the containing directory. Ie, CRTIME and updated when moved + * into a different directory. This can be retrieved with getxattr + * "FinderInfo" or the getattrlist() syscall. + */ + ZPL_ADDTIME, + ZPL_DOCUMENTID, + ZPL_END } zpl_attr_t; diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 2f266f53247e..4798e4cdd459 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -112,6 +112,9 @@ extern "C" { #define SA_ZPL_PAD(z) z->z_attr_table[ZPL_PAD] #define SA_ZPL_PROJID(z) z->z_attr_table[ZPL_PROJID] +#define SA_ZPL_ADDTIME(z) z->z_attr_table[ZPL_ADDTIME] +#define SA_ZPL_DOCUMENTID(z) z->z_attr_table[ZPL_DOCUMENTID] + /* * Is ID ephemeral? */ diff --git a/include/sys/zio.h b/include/sys/zio.h index e1f4d5c04499..a4c93697a981 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -520,6 +520,10 @@ struct zio { kcondvar_t io_cv; int io_allocator; +#ifdef ZIO_OS_FIELDS + ZIO_OS_FIELDS +#endif + /* FMA state */ zio_cksum_report_t *io_cksum_report; uint64_t io_ena; diff --git a/include/sys/zio_crypt.h b/include/sys/zio_crypt.h index 6a3efabb0405..75b2dd962160 100644 --- a/include/sys/zio_crypt.h +++ b/include/sys/zio_crypt.h @@ -148,6 +148,11 @@ int zio_crypt_do_hmac(zio_crypt_key_t *key, uint8_t *data, uint_t datalen, uint8_t *digestbuf, uint_t digestlen); int zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, boolean_t byteswap, uint8_t *portable_mac, uint8_t *local_mac); +#ifdef __APPLE__ +int zio_crypt_do_objset_hmacs_errata1(zio_crypt_key_t *key, void *data, + uint_t datalen, boolean_t should_bswap, uint8_t *portable_mac, + uint8_t *local_mac); +#endif int zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key, dmu_object_type_t ot, boolean_t byteswap, uint8_t *salt, uint8_t *iv, uint8_t *mac, uint_t datalen, uint8_t *plainbuf, uint8_t *cipherbuf, diff --git a/include/zfs_fletcher.h b/include/zfs_fletcher.h index ca1a092928d6..b61f428ef335 100644 --- a/include/zfs_fletcher.h +++ b/include/zfs_fletcher.h @@ -132,6 +132,7 @@ typedef struct fletcher_4_func { _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar_ops; _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar4_ops; +_ZFS_FLETCHER_H int fletcher_4_get(char *, size_t); #if defined(HAVE_SSE2) _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_sse2_ops; diff --git a/lib/Makefile.am b/lib/Makefile.am index 499ebdaeba9b..91ebc4b440d9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -54,6 +54,16 @@ noinst_LTLIBRARIES = lib_LTLIBRARIES = pkgconfig_DATA = + +if BUILD_MACOS +include $(srcdir)/%D%/os/macos/libdiskmgt/Makefile.am +include $(srcdir)/%D%/libefi/Makefile.am +endif + +if BUILD_LINUX +include $(srcdir)/%D%/libefi/Makefile.am +endif + include $(srcdir)/%D%/libavl/Makefile.am include $(srcdir)/%D%/libicp/Makefile.am include $(srcdir)/%D%/libnvpair/Makefile.am @@ -68,10 +78,6 @@ include $(srcdir)/%D%/libzfsbootenv/Makefile.am include $(srcdir)/%D%/libzpool/Makefile.am include $(srcdir)/%D%/libzstd/Makefile.am include $(srcdir)/%D%/libzutil/Makefile.am -if BUILD_LINUX -include $(srcdir)/%D%/libefi/Makefile.am -endif - PHONY += lib lib: $(noinst_LTLIBRARIES) $(lib_LTLIBRARIES) diff --git a/lib/libefi/Makefile.am b/lib/libefi/Makefile.am index 5c3e57346c86..f8abc88701be 100644 --- a/lib/libefi/Makefile.am +++ b/lib/libefi/Makefile.am @@ -5,7 +5,18 @@ libefi_la_CFLAGS += -fvisibility=hidden noinst_LTLIBRARIES += libefi.la CPPCHECKTARGETS += libefi.la -libefi_la_SOURCES = \ +libefi_la_SOURCES = +libefi_la_LDFLAGS = + +if BUILD_MACOS +libefi_la_SOURCES += \ + %D%/rdwr_efi_macos.c +libefi_la_LDFLAGS += -framework DiskArbitration -framework CoreServices +endif + +if BUILD_LINUX +libefi_la_SOURCES += \ %D%/rdwr_efi.c +endif libefi_la_LIBADD = $(LIBUUID_LIBS) $(ZLIB_LIBS) diff --git a/lib/libefi/rdwr_efi_macos.c b/lib/libefi/rdwr_efi_macos.c new file mode 100644 index 000000000000..3df30c0ce1da --- /dev/null +++ b/lib/libefi/rdwr_efi_macos.c @@ -0,0 +1,1598 @@ +/* + * 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) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2018 by Delphix. All rights reserved. + */ + +/* + * Copyright (c) 2013, 2020 Jorgen Lundman + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct uuid_to_ptag { + struct uuid uuid; +} conversion_array[] = { + { EFI_UNUSED }, + { EFI_BOOT }, + { EFI_ROOT }, + { EFI_SWAP }, + { EFI_USR }, + { EFI_BACKUP }, + { EFI_UNUSED }, /* STAND is never used */ + { EFI_VAR }, + { EFI_HOME }, + { EFI_ALTSCTR }, + { EFI_UNUSED }, /* CACHE (cachefs) is never used */ + { EFI_RESERVED }, + { EFI_SYSTEM }, + { EFI_LEGACY_MBR }, + { EFI_SYMC_PUB }, + { EFI_SYMC_CDS }, + { EFI_MSFT_RESV }, + { EFI_DELL_BASIC }, + { EFI_DELL_RAID }, + { EFI_DELL_SWAP }, + { EFI_DELL_LVM }, + { EFI_DELL_RESV }, + { EFI_AAPL_HFS }, + { EFI_AAPL_UFS }, + { EFI_FREEBSD_BOOT }, + { EFI_FREEBSD_SWAP }, + { EFI_FREEBSD_UFS }, + { EFI_FREEBSD_VINUM }, + { EFI_FREEBSD_ZFS }, + { EFI_BIOS_BOOT }, + { EFI_INTC_RS }, + { EFI_SNE_BOOT }, + { EFI_LENOVO_BOOT }, + { EFI_MSFT_LDMM }, + { EFI_MSFT_LDMD }, + { EFI_MSFT_RE }, + { EFI_IBM_GPFS }, + { EFI_MSFT_STORAGESPACES }, + { EFI_HPQ_DATA }, + { EFI_HPQ_SVC }, + { EFI_RHT_DATA }, + { EFI_RHT_HOME }, + { EFI_RHT_SRV }, + { EFI_RHT_DMCRYPT }, + { EFI_RHT_LUKS }, + { EFI_FREEBSD_DISKLABEL }, + { EFI_AAPL_RAID }, + { EFI_AAPL_RAIDOFFLINE }, + { EFI_AAPL_BOOT }, + { EFI_AAPL_LABEL }, + { EFI_AAPL_TVRECOVERY }, + { EFI_AAPL_CORESTORAGE }, + { EFI_NETBSD_SWAP }, + { EFI_NETBSD_FFS }, + { EFI_NETBSD_LFS }, + { EFI_NETBSD_RAID }, + { EFI_NETBSD_CAT }, + { EFI_NETBSD_CRYPT }, + { EFI_GOOG_KERN }, + { EFI_GOOG_ROOT }, + { EFI_GOOG_RESV }, + { EFI_HAIKU_BFS }, + { EFI_MIDNIGHTBSD_BOOT }, + { EFI_MIDNIGHTBSD_DATA }, + { EFI_MIDNIGHTBSD_SWAP }, + { EFI_MIDNIGHTBSD_UFS }, + { EFI_MIDNIGHTBSD_VINUM }, + { EFI_MIDNIGHTBSD_ZFS }, + { EFI_CEPH_JOURNAL }, + { EFI_CEPH_DMCRYPTJOURNAL }, + { EFI_CEPH_OSD }, + { EFI_CEPH_DMCRYPTOSD }, + { EFI_CEPH_CREATE }, + { EFI_CEPH_DMCRYPTCREATE }, + { EFI_OPENBSD_DISKLABEL }, + { EFI_BBRY_QNX }, + { EFI_BELL_PLAN9 }, + { EFI_VMW_KCORE }, + { EFI_VMW_VMFS }, + { EFI_VMW_RESV }, + { EFI_RHT_ROOTX86 }, + { EFI_RHT_ROOTAMD64 }, + { EFI_RHT_ROOTARM }, + { EFI_RHT_ROOTARM64 }, + { EFI_ACRONIS_SECUREZONE }, + { EFI_ONIE_BOOT }, + { EFI_ONIE_CONFIG }, + { EFI_IBM_PPRPBOOT }, + { EFI_FREEDESKTOP_BOOT } +}; + +#ifdef DEBUG +int efi_debug = 1; +#else +int efi_debug = 0; +#endif + +static int efi_read(int, struct dk_gpt *); +/* Additional macOS support functions */ + +#include +#include +#include +#include + +static const CFStringRef CoreStorageLogicalVolumeMediaPathSubstring = + CFSTR("/CoreStoragePhysical/"); +static const CFStringRef VirtualInterfaceDeviceProtocolSubstring = + CFSTR(kIOPropertyPhysicalInterconnectTypeVirtual); + +typedef struct { + DASessionRef session; + DADiskRef disk; +} DADiskSession; + +static Boolean +CFDictionaryValueIfPresentMatchesSubstring(CFDictionaryRef dict, + CFStringRef key, CFStringRef substr) +{ + Boolean ret = false; + CFStringRef existing; + if (dict && + CFDictionaryGetValueIfPresent(dict, key, + (const void **)&existing)) { + CFRange range = CFStringFind(existing, substr, + kCFCompareCaseInsensitive); + if (range.location != kCFNotFound) + ret = true; + } + return (ret); +} + +static int +setupDADiskSession(DADiskSession *ds, const char *bsdName) +{ + int err = 0; + + ds->session = DASessionCreate(NULL); + if (ds->session == NULL) { + err = EINVAL; + } + + if (err == 0) { + ds->disk = DADiskCreateFromBSDName(NULL, ds->session, bsdName); + if (ds->disk == NULL) + err = EINVAL; + } + return (err); +} + +static void +teardownDADiskSession(DADiskSession *ds) +{ + if (ds->session != NULL) + CFRelease(ds->session); + if (ds->disk != NULL) + CFRelease(ds->disk); +} + +static int +isDeviceMatchForKeyAndSubstr(char *device, CFStringRef key, CFStringRef substr, + Boolean *isMatch) +{ + int error; + DADiskSession ds = { 0 }; + + if (!isMatch) + return (-1); + + if ((error = setupDADiskSession(&ds, device)) == 0) { + CFDictionaryRef descDict = NULL; + if ((descDict = DADiskCopyDescription(ds.disk)) != NULL) { + *isMatch = + CFDictionaryValueIfPresentMatchesSubstring(descDict, + key, substr); + } else { + error = -1; + (void) fprintf(stderr, + "no DADiskCopyDescription for device %s\n", + device); + *isMatch = false; + } + } + + teardownDADiskSession(&ds); + return (error); +} + +/* + * Caller is responsible for supplying a /dev/disk* block device path + * or the BSD name (disk*). + */ +static int +osx_device_isvirtual(char *device) +{ + Boolean isCoreStorageLV = false; + Boolean isVirtualInterface = false; + + if (efi_debug) + (void) fprintf(stderr, "Checking if '%s' is virtual\n", device); + + isDeviceMatchForKeyAndSubstr(device, + kDADiskDescriptionMediaPathKey, + CoreStorageLogicalVolumeMediaPathSubstring, + &isCoreStorageLV); + + isDeviceMatchForKeyAndSubstr(device, + kDADiskDescriptionDeviceProtocolKey, + VirtualInterfaceDeviceProtocolSubstring, + &isVirtualInterface); + + if (efi_debug) + (void) fprintf(stderr, + "Is CoreStorage LV %d : is virtual interface %d\n", + isCoreStorageLV, + isVirtualInterface); + + return (isCoreStorageLV /* || isVirtualInterface*/); +} + +/* + * Return a 32-bit CRC of the contents of the buffer. Pre-and-post + * one's conditioning will be handled by crc32() internally. + */ +static uint32_t +efi_crc32(const unsigned char *buf, unsigned int size) +{ + uint32_t crc = crc32(0, Z_NULL, 0); + + crc = crc32(crc, buf, size); + + return (crc); +} + +static int +read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize) +{ + int sector_size; + unsigned long long capacity_size; + + if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) < 0) + return (-1); + + if (ioctl(fd, DKIOCGETBLOCKCOUNT, &capacity_size) < 0) + return (-1); + + *lbsize = (uint_t)sector_size; + *capacity = (diskaddr_t)(capacity_size); + + return (0); +} + +static int +efi_get_info(int fd, struct dk_cinfo *dki_info) +{ + int rval = 0; + + // DKIOCISVIRTUAL 32bit + // DKIOCISSOLIDSTATE 32bit + char pathbuf[PATH_MAX]; + ushort_t poi; + if (fcntl(fd, F_GETPATH, pathbuf) >= 0) { + if ((strncmp(pathbuf, "/dev/disk", 9) == 0)) { + strcpy(dki_info->dki_cname, "disk"); + dki_info->dki_ctype = DKC_DIRECT; + rval = sscanf(pathbuf, "/dev/disk%hus%hu", + &poi, + &dki_info->dki_partition); + + switch (rval) { + case 0: + errno = EINVAL; + goto error; + case 1: + dki_info->dki_partition = 0; + } + strlcpy(dki_info->dki_dname, + &pathbuf[5], + sizeof (dki_info->dki_dname)); + } + + /* + * rdisk in OSX do not have partitions, also it will fail. Use + * disk instead. + */ + if ((strncmp(pathbuf, "/dev/rdisk", 10) == 0)) { + strcpy(dki_info->dki_cname, "disk"); + dki_info->dki_ctype = DKC_DIRECT; + dki_info->dki_partition = 0; + + rval = sscanf(pathbuf, "/dev/r%[a-zA-Z0-9]", + dki_info->dki_dname); + } + + if (efi_debug) + (void) fprintf(stderr, + "rval %d, name '%s' and part %d\n", + rval, + dki_info->dki_dname, + dki_info->dki_partition); + } + + if (osx_device_isvirtual(dki_info->dki_dname)) { + dki_info->dki_ctype = DKC_VBD; + if (efi_debug) + (void) fprintf(stderr, + "'%s' is virtual\n", + pathbuf); + } else { + if (efi_debug) + (void) fprintf(stderr, + "'%s' is not virtual\n", + pathbuf); + } + + return (0); +error: + if (efi_debug) + (void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno); + + switch (errno) { + case EIO: + return (VT_EIO); + case EINVAL: + return (VT_EINVAL); + default: + return (VT_ERROR); + } +} + +/* + * the number of blocks the EFI label takes up (round up to nearest + * block) + */ +#define NBLOCKS(p, l) (1 + ((((p) * (int)sizeof (efi_gpe_t)) + \ + ((l) - 1)) / (l))) +/* number of partitions -- limited by what we can malloc */ +#define MAX_PARTS ((4294967295UL - sizeof (struct dk_gpt)) / \ + sizeof (struct dk_part)) + +int +efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc) +{ + diskaddr_t capacity = 0; + uint_t lbsize = 0; + uint_t nblocks; + size_t length; + struct dk_gpt *vptr; + struct uuid uuid; + struct dk_cinfo dki_info; + + if (read_disk_info(fd, &capacity, &lbsize) != 0) + return (-1); + + if (efi_get_info(fd, &dki_info) != 0) + return (-1); + + if (dki_info.dki_partition != 0) + return (-1); + + if ((dki_info.dki_ctype == DKC_PCMCIA_MEM) || + (dki_info.dki_ctype == DKC_VBD) || + (dki_info.dki_ctype == DKC_UNKNOWN)) + return (-1); + + nblocks = NBLOCKS(nparts, lbsize); + if ((nblocks * lbsize) < EFI_MIN_ARRAY_SIZE + lbsize) { + /* 16K plus one block for the GPT */ + nblocks = EFI_MIN_ARRAY_SIZE / lbsize + 1; + } + + if (nparts > MAX_PARTS) { + if (efi_debug) { + (void) fprintf(stderr, + "the maximum number of partitions supported is %lu\n", + MAX_PARTS); + } + return (-1); + } + + length = sizeof (struct dk_gpt) + + sizeof (struct dk_part) * (nparts - 1); + + vptr = calloc(1, length); + if (vptr == NULL) + return (-1); + + *vtoc = vptr; + + vptr->efi_version = EFI_VERSION_CURRENT; + vptr->efi_lbasize = lbsize; + vptr->efi_nparts = nparts; + /* + * add one block here for the PMBR; on disks with a 512 byte + * block size and 128 or fewer partitions, efi_first_u_lba + * should work out to "34" + */ + vptr->efi_first_u_lba = nblocks + 1; + vptr->efi_last_lba = capacity - 1; + vptr->efi_altern_lba = capacity -1; + vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks; + + (void) uuid_generate((uchar_t *)&uuid); + UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid); + return (0); +} + +/* + * Read EFI - return partition number upon success. + */ +int +efi_alloc_and_read(int fd, struct dk_gpt **vtoc) +{ + int rval; + uint32_t nparts; + int length; + struct dk_gpt *vptr; + + /* figure out the number of entries that would fit into 16K */ + nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t); + length = (int) sizeof (struct dk_gpt) + + (int) sizeof (struct dk_part) * (nparts - 1); + vptr = calloc(1, length); + + if (vptr == NULL) + return (VT_ERROR); + + vptr->efi_nparts = nparts; + rval = efi_read(fd, vptr); + + if ((rval == VT_EINVAL) && vptr->efi_nparts > nparts) { + void *tmp; + length = (int) sizeof (struct dk_gpt) + + (int) sizeof (struct dk_part) * (vptr->efi_nparts - 1); + nparts = vptr->efi_nparts; + if ((tmp = realloc(vptr, length)) == NULL) { + free(vptr); + *vtoc = NULL; + return (VT_ERROR); + } else { + vptr = tmp; + rval = efi_read(fd, vptr); + } + } + + if (rval < 0) { + if (efi_debug) { + (void) fprintf(stderr, + "read of EFI table failed, rval=%d\n", rval); + } + free(vptr); + *vtoc = NULL; + } else { + *vtoc = vptr; + } + + return (rval); +} + +static int +efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc) +{ + void *data = dk_ioc->dki_data; + int error; + diskaddr_t capacity; + uint_t lbsize; + + /* + * When the IO is not being performed in kernel as an ioctl we need + * to know the sector size so we can seek to the proper byte offset. + */ + if (read_disk_info(fd, &capacity, &lbsize) == -1) { + if (efi_debug) + fprintf(stderr, "unable to read disk info: %d", errno); + + errno = EIO; + return (-1); + } + + switch (cmd) { + case DKIOCGETEFI: + if (lbsize == 0) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCGETEFI assuming " + "LBA %d bytes\n", DEV_BSIZE); + + lbsize = DEV_BSIZE; + } + + error = lseek(fd, dk_ioc->dki_lba * lbsize, SEEK_SET); + if (error == -1) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCGETEFI lseek " + "error: %d\n", errno); + return (error); + } + + error = read(fd, data, dk_ioc->dki_length); + if (error == -1) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCGETEFI read " + "error: %d\n", errno); + return (error); + } + + if (error != dk_ioc->dki_length) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCGETEFI short " + "read of %d bytes\n", error); + errno = EIO; + return (-1); + } + error = 0; + break; + + case DKIOCSETEFI: + if (lbsize == 0) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCSETEFI unknown " + "LBA size\n"); + errno = EIO; + return (-1); + } + + error = lseek(fd, dk_ioc->dki_lba * lbsize, SEEK_SET); + if (error == -1) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCSETEFI lseek " + "error: %d\n", errno); + return (error); + } + + error = write(fd, data, dk_ioc->dki_length); + if (error == -1) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCSETEFI write " + "error: %d\n", errno); + return (error); + } + + if (error != dk_ioc->dki_length) { + if (efi_debug) + (void) fprintf(stderr, "DKIOCSETEFI short " + "write of %d bytes\n", error); + errno = EIO; + return (-1); + } + + /* Sync the new EFI table to disk */ + error = fsync(fd); + if (error == -1) + return (error); + + error = 0; + break; + + default: + if (efi_debug) + (void) fprintf(stderr, "unsupported ioctl()\n"); + + errno = EIO; + return (-1); + } + + return (error); +} + +int +efi_rescan(int fd) +{ + (void) fd; + return (0); +} + +static int +check_label(int fd, dk_efi_t *dk_ioc) +{ + efi_gpt_t *efi; + uint_t crc; + + if (efi_ioctl(fd, DKIOCGETEFI, dk_ioc) == -1) { + switch (errno) { + case EIO: + return (VT_EIO); + default: + return (VT_ERROR); + } + } + efi = dk_ioc->dki_data; + if (efi->efi_gpt_Signature != LE_64(EFI_SIGNATURE)) { + if (efi_debug) + (void) fprintf(stderr, + "Bad EFI signature: 0x%llx != 0x%llx\n", + (long long)efi->efi_gpt_Signature, + (long long)LE_64(EFI_SIGNATURE)); + return (VT_EINVAL); + } + + /* + * check CRC of the header; the size of the header should + * never be larger than one block + */ + crc = efi->efi_gpt_HeaderCRC32; + efi->efi_gpt_HeaderCRC32 = 0; + len_t headerSize = (len_t)LE_32(efi->efi_gpt_HeaderSize); + + if (headerSize < EFI_MIN_LABEL_SIZE || headerSize > EFI_LABEL_SIZE) { + if (efi_debug) + (void) fprintf(stderr, + "Invalid EFI HeaderSize %llu. Assuming %d.\n", + headerSize, EFI_MIN_LABEL_SIZE); + } + + if ((headerSize > dk_ioc->dki_length) || + crc != LE_32(efi_crc32((unsigned char *)efi, headerSize))) { + if (efi_debug) + (void) fprintf(stderr, + "Bad EFI CRC: 0x%x != 0x%x\n", + crc, LE_32(efi_crc32((unsigned char *)efi, + headerSize))); + return (VT_EINVAL); + } + + return (0); +} + +static int +efi_read(int fd, struct dk_gpt *vtoc) +{ + int i, j; + int label_len; + int rval = 0; + int md_flag = 0; + int vdc_flag = 0; + diskaddr_t capacity = 0; + uint_t lbsize = 0; + struct dk_minfo disk_info; + dk_efi_t dk_ioc; + efi_gpt_t *efi; + efi_gpe_t *efi_parts; + struct dk_cinfo dki_info; + uint32_t user_length; + boolean_t legacy_label = B_FALSE; + + /* + * get the partition number for this file descriptor. + */ + if ((rval = efi_get_info(fd, &dki_info)) != 0) + return (rval); + + if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) && + (strncmp(dki_info.dki_dname, "md", 3) == 0)) { + md_flag++; + } else if ((strncmp(dki_info.dki_cname, "vdc", 4) == 0) && + (strncmp(dki_info.dki_dname, "vdc", 4) == 0)) { + /* + * The controller and drive name "vdc" (virtual disk client) + * indicates a LDoms virtual disk. + */ + vdc_flag++; + } + + /* get the LBA size */ + if (read_disk_info(fd, &capacity, &lbsize) == -1) { + if (efi_debug) { + (void) fprintf(stderr, + "unable to read disk info: %d", + errno); + } + return (VT_EINVAL); + } + + disk_info.dki_lbsize = lbsize; + disk_info.dki_capacity = capacity; + + if (disk_info.dki_lbsize == 0) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_read: assuming LBA 512 bytes\n"); + } + disk_info.dki_lbsize = DEV_BSIZE; + } + /* + * Read the EFI GPT to figure out how many partitions we need + * to deal with. + */ + dk_ioc.dki_lba = 1; + if (NBLOCKS(vtoc->efi_nparts, disk_info.dki_lbsize) < 34) { + label_len = EFI_MIN_ARRAY_SIZE + disk_info.dki_lbsize; + } else { + label_len = vtoc->efi_nparts * (int) sizeof (efi_gpe_t) + + disk_info.dki_lbsize; + if (label_len % disk_info.dki_lbsize) { + /* pad to physical sector size */ + label_len += disk_info.dki_lbsize; + label_len &= ~(disk_info.dki_lbsize - 1); + } + } + + if (posix_memalign((void **)&dk_ioc.dki_data, + disk_info.dki_lbsize, label_len)) + return (VT_ERROR); + + memset(dk_ioc.dki_data, 0, label_len); + dk_ioc.dki_length = disk_info.dki_lbsize; + user_length = vtoc->efi_nparts; + efi = dk_ioc.dki_data; + if (md_flag) { + dk_ioc.dki_length = label_len; + if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) { + switch (errno) { + case EIO: + return (VT_EIO); + default: + return (VT_ERROR); + } + } + } else if ((rval = check_label(fd, &dk_ioc)) == VT_EINVAL) { + /* + * No valid label here; try the alternate. Note that here + * we just read GPT header and save it into dk_ioc.data, + * Later, we will read GUID partition entry array if we + * can get valid GPT header. + */ + + /* + * This is a workaround for legacy systems. In the past, the + * last sector of SCSI disk was invisible on x86 platform. At + * that time, backup label was saved on the next to the last + * sector. It is possible for users to move a disk from previous + * solaris system to present system. Here, we attempt to search + * legacy backup EFI label first. + */ + dk_ioc.dki_lba = disk_info.dki_capacity - 2; + dk_ioc.dki_length = disk_info.dki_lbsize; + rval = check_label(fd, &dk_ioc); + if (rval == VT_EINVAL) { + /* + * we didn't find legacy backup EFI label, try to + * search backup EFI label in the last block. + */ + dk_ioc.dki_lba = disk_info.dki_capacity - 1; + dk_ioc.dki_length = disk_info.dki_lbsize; + rval = check_label(fd, &dk_ioc); + if (rval == 0) { + legacy_label = B_TRUE; + if (efi_debug) + (void) fprintf(stderr, + "efi_read: primary label corrupt; " + "using EFI backup label located on" + " the last block\n"); + } + } else { + if ((efi_debug) && (rval == 0)) + (void) fprintf(stderr, "efi_read: primary label" + " corrupt; using legacy EFI backup label " + " located on the next to last block\n"); + } + + if (rval == 0) { + dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA); + vtoc->efi_flags |= EFI_GPT_PRIMARY_CORRUPT; + vtoc->efi_nparts = + LE_32(efi->efi_gpt_NumberOfPartitionEntries); + /* + * Partition tables are between backup GPT header + * table and ParitionEntryLBA (the starting LBA of + * the GUID partition entries array). Now that we + * already got valid GPT header and saved it in + * dk_ioc.dki_data, we try to get GUID partition + * entry array here. + */ + /* LINTED */ + dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data + + disk_info.dki_lbsize); + if (legacy_label) + dk_ioc.dki_length = disk_info.dki_capacity - 1 - + dk_ioc.dki_lba; + else + dk_ioc.dki_length = disk_info.dki_capacity - 2 - + dk_ioc.dki_lba; + dk_ioc.dki_length *= disk_info.dki_lbsize; + if (dk_ioc.dki_length > + ((len_t)label_len - sizeof (*dk_ioc.dki_data))) { + rval = VT_EINVAL; + } else { + /* + * read GUID partition entry array + */ + rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc); + } + } + + } else if (rval == 0) { + + dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA); + /* LINTED */ + dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data + + disk_info.dki_lbsize); + dk_ioc.dki_length = label_len - disk_info.dki_lbsize; + rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc); + + } else if (vdc_flag && rval == VT_ERROR && errno == EINVAL) { + /* + * When the device is a LDoms virtual disk, the DKIOCGETEFI + * ioctl can fail with EINVAL if the virtual disk backend + * is a ZFS volume serviced by a domain running an old version + * of Solaris. This is because the DKIOCGETEFI ioctl was + * initially incorrectly implemented for a ZFS volume and it + * expected the GPT and GPE to be retrieved with a single ioctl. + * So we try to read the GPT and the GPE using that old style + * ioctl. + */ + dk_ioc.dki_lba = 1; + dk_ioc.dki_length = label_len; + rval = check_label(fd, &dk_ioc); + } + + if (rval < 0) { + free(efi); + return (rval); + } + + /* LINTED -- always longlong aligned */ + efi_parts = (efi_gpe_t *)(((char *)efi) + disk_info.dki_lbsize); + + /* + * Assemble this into a "dk_gpt" struct for easier + * digestibility by applications. + */ + vtoc->efi_version = LE_32(efi->efi_gpt_Revision); + vtoc->efi_nparts = LE_32(efi->efi_gpt_NumberOfPartitionEntries); + vtoc->efi_part_size = LE_32(efi->efi_gpt_SizeOfPartitionEntry); + vtoc->efi_lbasize = disk_info.dki_lbsize; + vtoc->efi_last_lba = disk_info.dki_capacity - 1; + vtoc->efi_first_u_lba = LE_64(efi->efi_gpt_FirstUsableLBA); + vtoc->efi_last_u_lba = LE_64(efi->efi_gpt_LastUsableLBA); + vtoc->efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA); + UUID_LE_CONVERT(vtoc->efi_disk_uguid, efi->efi_gpt_DiskGUID); + + /* + * If the array the user passed in is too small, set the length + * to what it needs to be and return + */ + if (user_length < vtoc->efi_nparts) { + return (VT_EINVAL); + } + + for (i = 0; i < vtoc->efi_nparts; i++) { + + UUID_LE_CONVERT(vtoc->efi_parts[i].p_guid, + efi_parts[i].efi_gpe_PartitionTypeGUID); + + for (j = 0; + j < sizeof (conversion_array) + / sizeof (struct uuid_to_ptag); j++) { + + if (memcmp(&vtoc->efi_parts[i].p_guid, + &conversion_array[j].uuid, + sizeof (struct uuid)) == 0) { + vtoc->efi_parts[i].p_tag = j; + break; + } + } + if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) + continue; + vtoc->efi_parts[i].p_flag = + LE_16(efi_parts[i].efi_gpe_Attributes.PartitionAttrs); + vtoc->efi_parts[i].p_start = + LE_64(efi_parts[i].efi_gpe_StartingLBA); + vtoc->efi_parts[i].p_size = + LE_64(efi_parts[i].efi_gpe_EndingLBA) - + vtoc->efi_parts[i].p_start + 1; + for (j = 0; j < EFI_PART_NAME_LEN; j++) { + vtoc->efi_parts[i].p_name[j] = + (uchar_t)LE_16( + efi_parts[i].efi_gpe_PartitionName[j]); + } + + UUID_LE_CONVERT(vtoc->efi_parts[i].p_uguid, + efi_parts[i].efi_gpe_UniquePartitionGUID); + } + free(efi); + + return (dki_info.dki_partition); +} + +/* writes a "protective" MBR */ +static int +write_pmbr(int fd, struct dk_gpt *vtoc) +{ + dk_efi_t dk_ioc; + struct mboot mb; + uchar_t *cp; + diskaddr_t size_in_lba; + uchar_t *buf; + int len; + + len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize; + if (posix_memalign((void **)&buf, len, len)) + return (VT_ERROR); + + /* + * Preserve any boot code and disk signature if the first block is + * already an MBR. + */ + memset(buf, 0, len); + dk_ioc.dki_lba = 0; + dk_ioc.dki_length = len; + /* LINTED -- always longlong aligned */ + dk_ioc.dki_data = (efi_gpt_t *)buf; + if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) { + (void) memcpy(&mb, buf, sizeof (mb)); + memset(&mb, 0, sizeof (mb)); + mb.signature = LE_16(MBB_MAGIC); + } else { + (void) memcpy(&mb, buf, sizeof (mb)); + if (mb.signature != LE_16(MBB_MAGIC)) { + memset(&mb, 0, sizeof (mb)); + mb.signature = LE_16(MBB_MAGIC); + } + } + + memset(&mb.parts, 0, sizeof (mb.parts)); + cp = (uchar_t *)&mb.parts[0]; + /* bootable or not */ + *cp++ = 0; + /* beginning CHS; 0xffffff if not representable */ + *cp++ = 0xff; + *cp++ = 0xff; + *cp++ = 0xff; + /* OS type */ + *cp++ = EFI_PMBR; + /* ending CHS; 0xffffff if not representable */ + *cp++ = 0xff; + *cp++ = 0xff; + *cp++ = 0xff; + /* starting LBA: 1 (little endian format) by EFI definition */ + *cp++ = 0x01; + *cp++ = 0x00; + *cp++ = 0x00; + *cp++ = 0x00; + /* ending LBA: last block on the disk (little endian format) */ + size_in_lba = vtoc->efi_last_lba; + if (size_in_lba < 0xffffffff) { + *cp++ = (size_in_lba & 0x000000ff); + *cp++ = (size_in_lba & 0x0000ff00) >> 8; + *cp++ = (size_in_lba & 0x00ff0000) >> 16; + *cp++ = (size_in_lba & 0xff000000) >> 24; + } else { + *cp++ = 0xff; + *cp++ = 0xff; + *cp++ = 0xff; + *cp++ = 0xff; + } + + (void) memcpy(buf, &mb, sizeof (mb)); + /* LINTED -- always longlong aligned */ + dk_ioc.dki_data = (efi_gpt_t *)buf; + dk_ioc.dki_lba = 0; + dk_ioc.dki_length = len; + if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { + free(buf); + switch (errno) { + case EIO: + return (VT_EIO); + case EINVAL: + return (VT_EINVAL); + default: + return (VT_ERROR); + } + } + free(buf); + return (0); +} + +/* make sure the user specified something reasonable */ +static int +check_input(struct dk_gpt *vtoc) +{ + int resv_part = -1; + int i, j; + diskaddr_t istart, jstart, isize, jsize, endsect; + + /* + * Sanity-check the input (make sure no partitions overlap) + */ + for (i = 0; i < vtoc->efi_nparts; i++) { + /* It can't be unassigned and have an actual size */ + if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && + (vtoc->efi_parts[i].p_size != 0)) { + if (efi_debug) { + (void) fprintf(stderr, "partition %d is " + "\"unassigned\" but has a size of %llu", + i, vtoc->efi_parts[i].p_size); + } + return (VT_EINVAL); + } + if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) { + if (uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_guid)) + continue; + /* we have encountered an unknown uuid */ + vtoc->efi_parts[i].p_tag = 0xff; + } + if (vtoc->efi_parts[i].p_tag == V_RESERVED) { + if (resv_part != -1) { + if (efi_debug) { + (void) fprintf(stderr, "found " + "duplicate reserved partition " + "at %d\n", i); + } + return (VT_EINVAL); + } + resv_part = i; + } + if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || + (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { + if (efi_debug) { + (void) fprintf(stderr, + "Partition %d starts at %llu. ", + i, + vtoc->efi_parts[i].p_start); + (void) fprintf(stderr, + "It must be between %llu and %llu.\n", + vtoc->efi_first_u_lba, + vtoc->efi_last_u_lba); + } + return (VT_EINVAL); + } + if ((vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size < + vtoc->efi_first_u_lba) || + (vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size > + vtoc->efi_last_u_lba + 1)) { + if (efi_debug) { + (void) fprintf(stderr, + "Partition %d ends at %llu. ", + i, + vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size); + (void) fprintf(stderr, + "It must be between %llu and %llu.\n", + vtoc->efi_first_u_lba, + vtoc->efi_last_u_lba); + } + return (VT_EINVAL); + } + + for (j = 0; j < vtoc->efi_nparts; j++) { + isize = vtoc->efi_parts[i].p_size; + jsize = vtoc->efi_parts[j].p_size; + istart = vtoc->efi_parts[i].p_start; + jstart = vtoc->efi_parts[j].p_start; + if ((i != j) && (isize != 0) && (jsize != 0)) { + endsect = jstart + jsize -1; + if ((jstart <= istart) && + (istart <= endsect)) { + if (efi_debug) { + (void) fprintf(stderr, + "Partition %d overlaps " + "partition %d.", i, j); + } + return (VT_EINVAL); + } + } + } + } + /* just a warning for now */ + if ((resv_part == -1) && efi_debug) { + (void) fprintf(stderr, + "no reserved partition found\n"); + } + return (0); +} + +/* + * add all the unallocated space to the current label + */ +int +efi_use_whole_disk(int fd) +{ + struct dk_gpt *efi_label = NULL; + int rval; + int i; + uint_t resv_index = 0, data_index = 0; + diskaddr_t resv_start = 0, data_start = 0; + diskaddr_t data_size, limit, difference; + boolean_t sync_needed = B_FALSE; + uint_t nblocks; + + rval = efi_alloc_and_read(fd, &efi_label); + if (rval < 0) { + if (efi_label != NULL) + efi_free(efi_label); + return (rval); + } + + /* + * Find the last physically non-zero partition. + * This should be the reserved partition. + */ + for (i = 0; i < efi_label->efi_nparts; i ++) { + if (resv_start < efi_label->efi_parts[i].p_start) { + resv_start = efi_label->efi_parts[i].p_start; + resv_index = i; + } + } + + /* + * Find the last physically non-zero partition before that. + * This is the data partition. + */ + for (i = 0; i < resv_index; i ++) { + if (data_start < efi_label->efi_parts[i].p_start) { + data_start = efi_label->efi_parts[i].p_start; + data_index = i; + } + } + data_size = efi_label->efi_parts[data_index].p_size; + + /* + * See the "efi_alloc_and_init" function for more information + * about where this "nblocks" value comes from. + */ + nblocks = efi_label->efi_first_u_lba - 1; + + /* + * Determine if the EFI label is out of sync. We check that: + * + * 1. the data partition ends at the limit we set, and + * 2. the reserved partition starts at the limit we set. + * + * If either of these conditions is not met, then we need to + * resync the EFI label. + * + * The limit is the last usable LBA, determined by the last LBA + * and the first usable LBA fields on the EFI label of the disk + * (see the lines directly above). Additionally, we factor in + * EFI_MIN_RESV_SIZE (per its use in "zpool_label_disk") and + * P2ALIGN it to ensure the partition boundaries are aligned + * (for performance reasons). The alignment should match the + * alignment used by the "zpool_label_disk" function. + */ + limit = P2ALIGN(efi_label->efi_last_lba - nblocks - EFI_MIN_RESV_SIZE, + PARTITION_END_ALIGNMENT); + if (data_start + data_size != limit || resv_start != limit) + sync_needed = B_TRUE; + + if (efi_debug && sync_needed) + (void) fprintf(stderr, "efi_use_whole_disk: sync needed\n"); + + /* + * If alter_lba is 1, we are using the backup label. + * Since we can locate the backup label by disk capacity, + * there must be no unallocated space. + */ + if ((efi_label->efi_altern_lba == 1) || (efi_label->efi_altern_lba + >= efi_label->efi_last_lba && !sync_needed)) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_use_whole_disk: requested space not found\n"); + } + efi_free(efi_label); + return (VT_ENOSPC); + } + + /* + * Verify that we've found the reserved partition by checking + * that it looks the way it did when we created it in zpool_label_disk. + * If we've found the incorrect partition, then we know that this + * device was reformatted and no longer is solely used by ZFS. + */ + if ((efi_label->efi_parts[resv_index].p_size != EFI_MIN_RESV_SIZE) || + (efi_label->efi_parts[resv_index].p_tag != V_RESERVED) || + (resv_index != 8)) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_use_whole_disk: wholedisk not available\n"); + } + efi_free(efi_label); + return (VT_ENOSPC); + } + + if (data_start + data_size != resv_start) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_use_whole_disk: " + "data_start (%lli) + " + "data_size (%lli) != " + "resv_start (%lli)\n", + data_start, data_size, resv_start); + } + + return (VT_EINVAL); + } + + if (limit < resv_start) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_use_whole_disk: " + "limit (%lli) < resv_start (%lli)\n", + limit, resv_start); + } + + return (VT_EINVAL); + } + + difference = limit - resv_start; + + if (efi_debug) + (void) fprintf(stderr, + "efi_use_whole_disk: difference is %lli\n", difference); + + /* + * Move the reserved partition. There is currently no data in + * here except fabricated devids (which get generated via + * efi_write()). So there is no need to copy data. + */ + efi_label->efi_parts[data_index].p_size += difference; + efi_label->efi_parts[resv_index].p_start += difference; + efi_label->efi_last_u_lba = efi_label->efi_last_lba - nblocks; + + rval = efi_write(fd, efi_label); + if (rval < 0) { + if (efi_debug) { + (void) fprintf(stderr, + "efi_use_whole_disk:fail to write label, rval=%d\n", + rval); + } + efi_free(efi_label); + return (rval); + } + + efi_free(efi_label); + return (0); +} + +/* + * write EFI label and backup label + */ +int +efi_write(int fd, struct dk_gpt *vtoc) +{ + dk_efi_t dk_ioc; + efi_gpt_t *efi; + efi_gpe_t *efi_parts; + int i, j; + struct dk_cinfo dki_info; + int rval; + int md_flag = 0; + int nblocks; + diskaddr_t lba_backup_gpt_hdr; + + if ((rval = efi_get_info(fd, &dki_info)) != 0) + return (rval); + + /* check if we are dealing with a metadevice */ + if ((strncmp(dki_info.dki_cname, "pseudo", 7) == 0) && + (strncmp(dki_info.dki_dname, "md", 3) == 0)) { + md_flag = 1; + } + + if (check_input(vtoc)) { + /* + * not valid; if it's a metadevice just pass it down + * because SVM will do its own checking + */ + if (md_flag == 0) { + return (VT_EINVAL); + } + } + + dk_ioc.dki_lba = 1; + if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) { + dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize; + } else { + dk_ioc.dki_length = (uint64_t)NBLOCKS(vtoc->efi_nparts, + vtoc->efi_lbasize) * + (uint64_t)vtoc->efi_lbasize; + } + + /* + * the number of blocks occupied by GUID partition entry array + */ + nblocks = dk_ioc.dki_length / vtoc->efi_lbasize - 1; + + /* + * Backup GPT header is located on the block after GUID + * partition entry array. Here, we calculate the address + * for backup GPT header. + */ + lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks; + if (posix_memalign((void **)&dk_ioc.dki_data, + vtoc->efi_lbasize, dk_ioc.dki_length)) + return (VT_ERROR); + + memset(dk_ioc.dki_data, 0, dk_ioc.dki_length); + efi = dk_ioc.dki_data; + + /* stuff user's input into EFI struct */ + efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE); + efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */ + efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt) - LEN_EFI_PAD); + efi->efi_gpt_Reserved1 = 0; + efi->efi_gpt_MyLBA = LE_64(1ULL); + efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr); + efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba); + efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba); + efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL); + efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts); + efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe)); + UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid); + + /* LINTED -- always longlong aligned */ + efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + vtoc->efi_lbasize); + + for (i = 0; i < vtoc->efi_nparts; i++) { + for (j = 0; + j < sizeof (conversion_array) / + sizeof (struct uuid_to_ptag); j++) { + + if (vtoc->efi_parts[i].p_tag == j) { + UUID_LE_CONVERT( + efi_parts[i].efi_gpe_PartitionTypeGUID, + conversion_array[j].uuid); + break; + } + } + + if (j == sizeof (conversion_array) / + sizeof (struct uuid_to_ptag)) { + /* + * If we didn't have a matching uuid match, bail here. + * Don't write a label with unknown uuid. + */ + if (efi_debug) { + (void) fprintf(stderr, + "Unknown uuid for p_tag %d\n", + vtoc->efi_parts[i].p_tag); + } + return (VT_EINVAL); + } + + /* Zero's should be written for empty partitions */ + if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) + continue; + + efi_parts[i].efi_gpe_StartingLBA = + LE_64(vtoc->efi_parts[i].p_start); + efi_parts[i].efi_gpe_EndingLBA = + LE_64(vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size - 1); + efi_parts[i].efi_gpe_Attributes.PartitionAttrs = + LE_16(vtoc->efi_parts[i].p_flag); + for (j = 0; j < EFI_PART_NAME_LEN; j++) { + efi_parts[i].efi_gpe_PartitionName[j] = + LE_16((ushort_t)vtoc->efi_parts[i].p_name[j]); + } + if ((vtoc->efi_parts[i].p_tag != V_UNASSIGNED) && + uuid_is_null((uchar_t *)&vtoc->efi_parts[i].p_uguid)) { + (void) uuid_generate((uchar_t *) + &vtoc->efi_parts[i].p_uguid); + } + memcpy( + &efi_parts[i].efi_gpe_UniquePartitionGUID, + &vtoc->efi_parts[i].p_uguid, + sizeof (uuid_t)); + } + efi->efi_gpt_PartitionEntryArrayCRC32 = + LE_32(efi_crc32((unsigned char *)efi_parts, + vtoc->efi_nparts * (int)sizeof (struct efi_gpe))); + efi->efi_gpt_HeaderCRC32 = + LE_32(efi_crc32((unsigned char *)efi, + LE_32(efi->efi_gpt_HeaderSize))); + + if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { + free(dk_ioc.dki_data); + switch (errno) { + case EIO: + return (VT_EIO); + case EINVAL: + return (VT_EINVAL); + default: + return (VT_ERROR); + } + } + /* if it's a metadevice we're done */ + if (md_flag) { + free(dk_ioc.dki_data); + return (0); + } + + /* write backup partition array */ + dk_ioc.dki_lba = vtoc->efi_last_u_lba + 1; + dk_ioc.dki_length -= vtoc->efi_lbasize; + /* LINTED */ + dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data + + vtoc->efi_lbasize); + + if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { + /* + * we wrote the primary label okay, so don't fail + */ + if (efi_debug) { + (void) fprintf(stderr, + "write of backup partitions to block %llu " + "failed, errno %d\n", + vtoc->efi_last_u_lba + 1, + errno); + } + } + /* + * now swap MyLBA and AlternateLBA fields and write backup + * partition table header + */ + dk_ioc.dki_lba = lba_backup_gpt_hdr; + dk_ioc.dki_length = vtoc->efi_lbasize; + /* LINTED */ + dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data - + vtoc->efi_lbasize); + efi->efi_gpt_AlternateLBA = LE_64(1ULL); + efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr); + efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1); + efi->efi_gpt_HeaderCRC32 = 0; + efi->efi_gpt_HeaderCRC32 = + LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data, + LE_32(efi->efi_gpt_HeaderSize))); + + if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { + if (efi_debug) { + (void) fprintf(stderr, + "write of backup header to block %llu failed, " + "errno %d\n", + lba_backup_gpt_hdr, + errno); + } + } + /* write the PMBR */ + (void) write_pmbr(fd, vtoc); + free(dk_ioc.dki_data); + + return (0); +} + +void +efi_free(struct dk_gpt *ptr) +{ + free(ptr); +} + +void +efi_err_check(struct dk_gpt *vtoc) +{ + int resv_part = -1; + int i, j; + diskaddr_t istart, jstart, isize, jsize, endsect; + int overlap = 0; + + /* + * make sure no partitions overlap + */ + for (i = 0; i < vtoc->efi_nparts; i++) { + /* It can't be unassigned and have an actual size */ + if ((vtoc->efi_parts[i].p_tag == V_UNASSIGNED) && + (vtoc->efi_parts[i].p_size != 0)) { + (void) fprintf(stderr, + "partition %d is \"unassigned\" but has a size " + "of %llu\n", i, vtoc->efi_parts[i].p_size); + } + if (vtoc->efi_parts[i].p_tag == V_UNASSIGNED) { + continue; + } + if (vtoc->efi_parts[i].p_tag == V_RESERVED) { + if (resv_part != -1) { + (void) fprintf(stderr, + "found duplicate reserved partition at " + "%d\n", i); + } + resv_part = i; + if (vtoc->efi_parts[i].p_size != EFI_MIN_RESV_SIZE) + (void) fprintf(stderr, + "Warning: reserved partition size must " + "be %d sectors\n", EFI_MIN_RESV_SIZE); + } + if ((vtoc->efi_parts[i].p_start < vtoc->efi_first_u_lba) || + (vtoc->efi_parts[i].p_start > vtoc->efi_last_u_lba)) { + (void) fprintf(stderr, + "Partition %d starts at %llu\n", + i, + vtoc->efi_parts[i].p_start); + (void) fprintf(stderr, + "It must be between %llu and %llu.\n", + vtoc->efi_first_u_lba, + vtoc->efi_last_u_lba); + } + if ((vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size < + vtoc->efi_first_u_lba) || + (vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size > + vtoc->efi_last_u_lba + 1)) { + (void) fprintf(stderr, + "Partition %d ends at %llu\n", + i, + vtoc->efi_parts[i].p_start + + vtoc->efi_parts[i].p_size); + (void) fprintf(stderr, + "It must be between %llu and %llu.\n", + vtoc->efi_first_u_lba, + vtoc->efi_last_u_lba); + } + + for (j = 0; j < vtoc->efi_nparts; j++) { + isize = vtoc->efi_parts[i].p_size; + jsize = vtoc->efi_parts[j].p_size; + istart = vtoc->efi_parts[i].p_start; + jstart = vtoc->efi_parts[j].p_start; + if ((i != j) && (isize != 0) && (jsize != 0)) { + endsect = jstart + jsize -1; + if ((jstart <= istart) && + (istart <= endsect)) { + if (!overlap) { + (void) fprintf(stderr, + "label error: EFI Labels do not " + "support overlapping partitions\n"); + } + (void) fprintf(stderr, + "Partition %d overlaps partition " + "%d.\n", i, j); + overlap = 1; + } + } + } + } + /* make sure there is a reserved partition */ + if (resv_part == -1) { + (void) fprintf(stderr, + "no reserved partition found\n"); + } +} diff --git a/lib/libicp/Makefile.am b/lib/libicp/Makefile.am index 4ba55b2158bc..257f71e3fbcd 100644 --- a/lib/libicp/Makefile.am +++ b/lib/libicp/Makefile.am @@ -9,6 +9,7 @@ nodist_libicp_la_SOURCES = \ module/icp/api/kcf_cipher.c \ module/icp/api/kcf_mac.c \ module/icp/algs/aes/aes_impl_aesni.c \ + module/icp/algs/aes/aes_impl_aesv8.c \ module/icp/algs/aes/aes_impl_generic.c \ module/icp/algs/aes/aes_impl_x86-64.c \ module/icp/algs/aes/aes_impl.c \ @@ -44,6 +45,7 @@ nodist_libicp_la_SOURCES = \ if TARGET_CPU_AARCH64 nodist_libicp_la_SOURCES += \ + module/icp/asm-aarch64/aes/aesv8-armx.S \ module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S \ module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S \ module/icp/asm-aarch64/sha2/sha256-armv8.S \ @@ -81,4 +83,3 @@ nodist_libicp_la_SOURCES += \ module/icp/asm-x86_64/blake3/blake3_sse2.S \ module/icp/asm-x86_64/blake3/blake3_sse41.S endif - diff --git a/lib/libnvpair/Makefile.am b/lib/libnvpair/Makefile.am index 87b8d32aa175..1c6ea889f18d 100644 --- a/lib/libnvpair/Makefile.am +++ b/lib/libnvpair/Makefile.am @@ -6,6 +6,27 @@ libnvpair_la_CFLAGS += -fvisibility=hidden %D%/libnvpair_la-libnvpair_json.$(OBJEXT) : CFLAGS += -Wno-type-limits %D%/libnvpair_la-libnvpair_json.l$(OBJEXT): CFLAGS += -Wno-type-limits + +if BUILD_MACOS +# See comment in macOS rpc/xdr.h, starting at: +# "A xdrproc_t exists for each data type which is to be encoded or decoded." +module/nvpair/nvpair.$(OBJEXT): CFLAGS += -Wno-incompatible-pointer-types +../../module/nvpair/nvpair.$(OBJEXT): CFLAGS += -Wwgat -Wno-incompatible-pointer-types +%D%/libnvpair_la-nvpair.$(OBJEXT) : CFLAGS += -Wno-type-limits +nvpair.$(OBJEXT) : CFLAGS += -Wno-type-limits2 +libnvpair_la-nvpair.$(OBJEXT) : CFLAGS += -Wno-type-limits3 +%D%/../../module/nvpair/libnvpair_la-nvpair.$(OBJEXT) : CFLAGS += -Wno-type-limits4 +endif +nvpair.lo : CFLAGS += -Wno-type-limits2 +libnvpair_la-nvpair.lo : CFLAGS += -Wno-type-limits2 +%D%/libnvpair_la-nvpair.lo : CFLAGS += -Wno-type-limits2 +../../module/nvpair/nvpair.lo : CFLAGS += -Wno-type-limits2 +module/nvpair/nvpair.lo : CFLAGS += -Wno-type-limits2 +module/nvpair/libnvpair_la-nvpair.lo : CFLAGS += -Wno-type-limits2 + + + + lib_LTLIBRARIES += libnvpair.la CPPCHECKTARGETS += libnvpair.la @@ -26,9 +47,11 @@ libnvpair_la_LIBADD += $(LIBTIRPC_LIBS) $(LTLIBINTL) libnvpair_la_LDFLAGS = +if !BUILD_MACOS if !ASAN_ENABLED libnvpair_la_LDFLAGS += -Wl,-z,defs endif +endif libnvpair_la_LDFLAGS += -version-info 3:0:0 diff --git a/lib/libshare/Makefile.am b/lib/libshare/Makefile.am index 48d8cb832428..c61b6a44e6b2 100644 --- a/lib/libshare/Makefile.am +++ b/lib/libshare/Makefile.am @@ -25,3 +25,9 @@ libshare_la_SOURCES += \ %D%/os/freebsd/nfs.c \ %D%/os/freebsd/smb.c endif + +if BUILD_MACOS +libshare_la_SOURCES += \ + %D%/os/macos/nfs.c \ + %D%/os/macos/smb.c +endif diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 822bef7e7a8d..9ab692418e2c 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -39,6 +39,13 @@ libspl_la_SOURCES += \ %D%/os/freebsd/zone.c endif +if BUILD_MACOS +libspl_la_SOURCES += \ + %D%/os/macos/getexecname.c \ + %D%/os/macos/gethostid.c \ + %D%/os/macos/zone.c +endif + libspl_la_LIBADD = \ libspl_assert.la diff --git a/lib/libspl/asm-x86_64/atomic.S b/lib/libspl/asm-x86_64/atomic.S new file mode 100644 index 000000000000..bb7dff12cc8e --- /dev/null +++ b/lib/libspl/asm-x86_64/atomic.S @@ -0,0 +1,693 @@ +/* + * 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 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + + .ident "%Z%%M% %I% %E% SMI" + + .file "%M%" + +#define _ASM +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#define SET_SIZE(x) +#elif __APPLE__ +#include +#endif + ENTRY(atomic_inc_8) + ALTENTRY(atomic_inc_uchar) + lock + incb (%rdi) + ret + SET_SIZE(atomic_inc_uchar) + SET_SIZE(atomic_inc_8) + + ENTRY(atomic_inc_16) + ALTENTRY(atomic_inc_ushort) + lock + incw (%rdi) + ret + SET_SIZE(atomic_inc_ushort) + SET_SIZE(atomic_inc_16) + + ENTRY(atomic_inc_32) + ALTENTRY(atomic_inc_uint) + lock + incl (%rdi) + ret + SET_SIZE(atomic_inc_uint) + SET_SIZE(atomic_inc_32) + + ENTRY(atomic_inc_64) + ALTENTRY(atomic_inc_ulong) + lock + incq (%rdi) + ret + SET_SIZE(atomic_inc_ulong) + SET_SIZE(atomic_inc_64) + + ENTRY(atomic_inc_8_nv) + ALTENTRY(atomic_inc_uchar_nv) + movb (%rdi), %al +1: + leaq 1(%rax), %rcx + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_inc_uchar_nv) + SET_SIZE(atomic_inc_8_nv) + + ENTRY(atomic_inc_16_nv) + ALTENTRY(atomic_inc_ushort_nv) + movw (%rdi), %ax +1: + leaq 1(%rax), %rcx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_inc_ushort_nv) + SET_SIZE(atomic_inc_16_nv) + + ENTRY(atomic_inc_32_nv) + ALTENTRY(atomic_inc_uint_nv) + movl (%rdi), %eax +1: + leaq 1(%rax), %rcx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_inc_uint_nv) + SET_SIZE(atomic_inc_32_nv) + + ENTRY(atomic_inc_64_nv) + ALTENTRY(atomic_inc_ulong_nv) + movq (%rdi), %rax +1: + leaq 1(%rax), %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_inc_ulong_nv) + SET_SIZE(atomic_inc_64_nv) + + ENTRY(atomic_dec_8) + ALTENTRY(atomic_dec_uchar) + lock + decb (%rdi) + ret + SET_SIZE(atomic_dec_uchar) + SET_SIZE(atomic_dec_8) + + ENTRY(atomic_dec_16) + ALTENTRY(atomic_dec_ushort) + lock + decw (%rdi) + ret + SET_SIZE(atomic_dec_ushort) + SET_SIZE(atomic_dec_16) + + ENTRY(atomic_dec_32) + ALTENTRY(atomic_dec_uint) + lock + decl (%rdi) + ret + SET_SIZE(atomic_dec_uint) + SET_SIZE(atomic_dec_32) + + ENTRY(atomic_dec_64) + ALTENTRY(atomic_dec_ulong) + lock + decq (%rdi) + ret + SET_SIZE(atomic_dec_ulong) + SET_SIZE(atomic_dec_64) + + ENTRY(atomic_dec_8_nv) + ALTENTRY(atomic_dec_uchar_nv) + movb (%rdi), %al +1: + leaq -1(%rax), %rcx + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_dec_uchar_nv) + SET_SIZE(atomic_dec_8_nv) + + ENTRY(atomic_dec_16_nv) + ALTENTRY(atomic_dec_ushort_nv) + movw (%rdi), %ax +1: + leaq -1(%rax), %rcx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_dec_ushort_nv) + SET_SIZE(atomic_dec_16_nv) + + ENTRY(atomic_dec_32_nv) + ALTENTRY(atomic_dec_uint_nv) + movl (%rdi), %eax +1: + leaq -1(%rax), %rcx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_dec_uint_nv) + SET_SIZE(atomic_dec_32_nv) + + ENTRY(atomic_dec_64_nv) + ALTENTRY(atomic_dec_ulong_nv) + movq (%rdi), %rax +1: + leaq -1(%rax), %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_dec_ulong_nv) + SET_SIZE(atomic_dec_64_nv) + + ENTRY(atomic_add_8) + ALTENTRY(atomic_add_char) + lock + addb %sil, (%rdi) + ret + SET_SIZE(atomic_add_char) + SET_SIZE(atomic_add_8) + + ENTRY(atomic_add_16) + ALTENTRY(atomic_add_short) + lock + addw %si, (%rdi) + ret + SET_SIZE(atomic_add_short) + SET_SIZE(atomic_add_16) + + ENTRY(atomic_add_32) + ALTENTRY(atomic_add_int) + lock + addl %esi, (%rdi) + ret + SET_SIZE(atomic_add_int) + SET_SIZE(atomic_add_32) + + ENTRY(atomic_add_64) + ALTENTRY(atomic_add_ptr) + ALTENTRY(atomic_add_long) + lock + addq %rsi, (%rdi) + ret + SET_SIZE(atomic_add_long) + SET_SIZE(atomic_add_ptr) + SET_SIZE(atomic_add_64) + + ENTRY(atomic_sub_8) + ALTENTRY(atomic_sub_char) + lock + subb %sil, (%rdi) + ret + SET_SIZE(atomic_sub_char) + SET_SIZE(atomic_sub_8) + + ENTRY(atomic_sub_16) + ALTENTRY(atomic_sub_short) + lock + subw %si, (%rdi) + ret + SET_SIZE(atomic_sub_short) + SET_SIZE(atomic_sub_16) + + ENTRY(atomic_sub_32) + ALTENTRY(atomic_sub_int) + lock + subl %esi, (%rdi) + ret + SET_SIZE(atomic_sub_int) + SET_SIZE(atomic_sub_32) + + ENTRY(atomic_sub_64) + ALTENTRY(atomic_sub_ptr) + ALTENTRY(atomic_sub_long) + lock + subq %rsi, (%rdi) + ret + SET_SIZE(atomic_sub_long) + SET_SIZE(atomic_sub_ptr) + SET_SIZE(atomic_sub_64) + + ENTRY(atomic_or_8) + ALTENTRY(atomic_or_uchar) + lock + orb %sil, (%rdi) + ret + SET_SIZE(atomic_or_uchar) + SET_SIZE(atomic_or_8) + + ENTRY(atomic_or_16) + ALTENTRY(atomic_or_ushort) + lock + orw %si, (%rdi) + ret + SET_SIZE(atomic_or_ushort) + SET_SIZE(atomic_or_16) + + ENTRY(atomic_or_32) + ALTENTRY(atomic_or_uint) + lock + orl %esi, (%rdi) + ret + SET_SIZE(atomic_or_uint) + SET_SIZE(atomic_or_32) + + ENTRY(atomic_or_64) + ALTENTRY(atomic_or_ulong) + lock + orq %rsi, (%rdi) + ret + SET_SIZE(atomic_or_ulong) + SET_SIZE(atomic_or_64) + + ENTRY(atomic_and_8) + ALTENTRY(atomic_and_uchar) + lock + andb %sil, (%rdi) + ret + SET_SIZE(atomic_and_uchar) + SET_SIZE(atomic_and_8) + + ENTRY(atomic_and_16) + ALTENTRY(atomic_and_ushort) + lock + andw %si, (%rdi) + ret + SET_SIZE(atomic_and_ushort) + SET_SIZE(atomic_and_16) + + ENTRY(atomic_and_32) + ALTENTRY(atomic_and_uint) + lock + andl %esi, (%rdi) + ret + SET_SIZE(atomic_and_uint) + SET_SIZE(atomic_and_32) + + ENTRY(atomic_and_64) + ALTENTRY(atomic_and_ulong) + lock + andq %rsi, (%rdi) + ret + SET_SIZE(atomic_and_ulong) + SET_SIZE(atomic_and_64) + + ENTRY(atomic_add_8_nv) + ALTENTRY(atomic_add_char_nv) + movb (%rdi), %al +1: + movb %sil, %cl + addb %al, %cl + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_add_char_nv) + SET_SIZE(atomic_add_8_nv) + + ENTRY(atomic_add_16_nv) + ALTENTRY(atomic_add_short_nv) + movw (%rdi), %ax +1: + movw %si, %cx + addw %ax, %cx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_add_short_nv) + SET_SIZE(atomic_add_16_nv) + + ENTRY(atomic_add_32_nv) + ALTENTRY(atomic_add_int_nv) + movl (%rdi), %eax +1: + movl %esi, %ecx + addl %eax, %ecx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_add_int_nv) + SET_SIZE(atomic_add_32_nv) + + ENTRY(atomic_add_64_nv) + ALTENTRY(atomic_add_ptr_nv) + ALTENTRY(atomic_add_long_nv) + movq (%rdi), %rax +1: + movq %rsi, %rcx + addq %rax, %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_add_long_nv) + SET_SIZE(atomic_add_ptr_nv) + SET_SIZE(atomic_add_64_nv) + + ENTRY(atomic_sub_8_nv) + ALTENTRY(atomic_sub_char_nv) + movb (%rdi), %al +1: + movb %sil, %cl + subb %al, %cl + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_sub_char_nv) + SET_SIZE(atomic_sub_8_nv) + + ENTRY(atomic_sub_16_nv) + ALTENTRY(atomic_sub_short_nv) + movw (%rdi), %ax +1: + movw %si, %cx + subw %ax, %cx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_sub_short_nv) + SET_SIZE(atomic_sub_16_nv) + + ENTRY(atomic_sub_32_nv) + ALTENTRY(atomic_sub_int_nv) + movl (%rdi), %eax +1: + movl %esi, %ecx + subl %eax, %ecx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_sub_int_nv) + SET_SIZE(atomic_sub_32_nv) + + ENTRY(atomic_sub_64_nv) + ALTENTRY(atomic_sub_ptr_nv) + ALTENTRY(atomic_sub_long_nv) + movq (%rdi), %rax +1: + movq %rsi, %rcx + subq %rax, %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_sub_long_nv) + SET_SIZE(atomic_sub_ptr_nv) + SET_SIZE(atomic_sub_64_nv) + + ENTRY(atomic_and_8_nv) + ALTENTRY(atomic_and_uchar_nv) + movb (%rdi), %al +1: + movb %sil, %cl + andb %al, %cl + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_and_uchar_nv) + SET_SIZE(atomic_and_8_nv) + + ENTRY(atomic_and_16_nv) + ALTENTRY(atomic_and_ushort_nv) + movw (%rdi), %ax +1: + movw %si, %cx + andw %ax, %cx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_and_ushort_nv) + SET_SIZE(atomic_and_16_nv) + + ENTRY(atomic_and_32_nv) + ALTENTRY(atomic_and_uint_nv) + movl (%rdi), %eax +1: + movl %esi, %ecx + andl %eax, %ecx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_and_uint_nv) + SET_SIZE(atomic_and_32_nv) + + ENTRY(atomic_and_64_nv) + ALTENTRY(atomic_and_ulong_nv) + movq (%rdi), %rax +1: + movq %rsi, %rcx + andq %rax, %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_and_ulong_nv) + SET_SIZE(atomic_and_64_nv) + + ENTRY(atomic_or_8_nv) + ALTENTRY(atomic_or_uchar_nv) + movb (%rdi), %al +1: + movb %sil, %cl + orb %al, %cl + lock + cmpxchgb %cl, (%rdi) + jne 1b + movzbl %cl, %eax + ret + SET_SIZE(atomic_and_uchar_nv) + SET_SIZE(atomic_and_8_nv) + + ENTRY(atomic_or_16_nv) + ALTENTRY(atomic_or_ushort_nv) + movw (%rdi), %ax +1: + movw %si, %cx + orw %ax, %cx + lock + cmpxchgw %cx, (%rdi) + jne 1b + movzwl %cx, %eax + ret + SET_SIZE(atomic_or_ushort_nv) + SET_SIZE(atomic_or_16_nv) + + ENTRY(atomic_or_32_nv) + ALTENTRY(atomic_or_uint_nv) + movl (%rdi), %eax +1: + movl %esi, %ecx + orl %eax, %ecx + lock + cmpxchgl %ecx, (%rdi) + jne 1b + movl %ecx, %eax + ret + SET_SIZE(atomic_or_uint_nv) + SET_SIZE(atomic_or_32_nv) + + ENTRY(atomic_or_64_nv) + ALTENTRY(atomic_or_ulong_nv) + movq (%rdi), %rax +1: + movq %rsi, %rcx + orq %rax, %rcx + lock + cmpxchgq %rcx, (%rdi) + jne 1b + movq %rcx, %rax + ret + SET_SIZE(atomic_or_ulong_nv) + SET_SIZE(atomic_or_64_nv) + + ENTRY(atomic_cas_8) + ALTENTRY(atomic_cas_uchar) + movzbl %sil, %eax + lock + cmpxchgb %dl, (%rdi) + ret + SET_SIZE(atomic_cas_uchar) + SET_SIZE(atomic_cas_8) + + ENTRY(atomic_cas_16) + ALTENTRY(atomic_cas_ushort) + movzwl %si, %eax + lock + cmpxchgw %dx, (%rdi) + ret + SET_SIZE(atomic_cas_ushort) + SET_SIZE(atomic_cas_16) + + ENTRY(atomic_cas_32) + ALTENTRY(atomic_cas_uint) + movl %esi, %eax + lock + cmpxchgl %edx, (%rdi) + ret + SET_SIZE(atomic_cas_uint) + SET_SIZE(atomic_cas_32) + + ENTRY(atomic_cas_64) + ALTENTRY(atomic_cas_ulong) + ALTENTRY(atomic_cas_ptr) + movq %rsi, %rax + lock + cmpxchgq %rdx, (%rdi) + ret + SET_SIZE(atomic_cas_ptr) + SET_SIZE(atomic_cas_ulong) + SET_SIZE(atomic_cas_64) + + ENTRY(atomic_swap_8) + ALTENTRY(atomic_swap_uchar) + movzbl %sil, %eax + lock + xchgb %al, (%rdi) + ret + SET_SIZE(atomic_swap_uchar) + SET_SIZE(atomic_swap_8) + + ENTRY(atomic_swap_16) + ALTENTRY(atomic_swap_ushort) + movzwl %si, %eax + lock + xchgw %ax, (%rdi) + ret + SET_SIZE(atomic_swap_ushort) + SET_SIZE(atomic_swap_16) + + ENTRY(atomic_swap_32) + ALTENTRY(atomic_swap_uint) + movl %esi, %eax + lock + xchgl %eax, (%rdi) + ret + SET_SIZE(atomic_swap_uint) + SET_SIZE(atomic_swap_32) + + ENTRY(atomic_swap_64) + ALTENTRY(atomic_swap_ulong) + ALTENTRY(atomic_swap_ptr) + movq %rsi, %rax + lock + xchgq %rax, (%rdi) + ret + SET_SIZE(atomic_swap_ptr) + SET_SIZE(atomic_swap_ulong) + SET_SIZE(atomic_swap_64) + + ENTRY(atomic_set_long_excl) + xorl %eax, %eax + lock + btsq %rsi, (%rdi) + jnc 1f + decl %eax +1: + ret + SET_SIZE(atomic_set_long_excl) + + ENTRY(atomic_clear_long_excl) + xorl %eax, %eax + lock + btrq %rsi, (%rdi) + jc 1f + decl %eax +1: + ret + SET_SIZE(atomic_clear_long_excl) + + /* + * NOTE: membar_enter, and membar_exit are identical routines. + * We define them separately, instead of using an ALTENTRY + * definitions to alias them together, so that DTrace and + * debuggers will see a unique address for them, allowing + * more accurate tracing. + */ + + ENTRY(membar_enter) + mfence + ret + SET_SIZE(membar_enter) + + ENTRY(membar_exit) + mfence + ret + SET_SIZE(membar_exit) + + ENTRY(membar_producer) + sfence + ret + SET_SIZE(membar_producer) + + ENTRY(membar_consumer) + lfence + ret + SET_SIZE(membar_consumer) + +#ifdef __ELF__ +.section .note.GNU-stack,"",%progbits +#endif diff --git a/lib/libspl/atomic.c b/lib/libspl/atomic.c index 8cc350710ba0..103949ecdffa 100644 --- a/lib/libspl/atomic.c +++ b/lib/libspl/atomic.c @@ -343,13 +343,13 @@ atomic_swap_ptr(volatile void *target, void *bits) uint64_t atomic_load_64(volatile uint64_t *target) { - return (__atomic_load_n(target, __ATOMIC_RELAXED)); + return (__atomic_load_n(target, __ATOMIC_ACQUIRE)); } void atomic_store_64(volatile uint64_t *target, uint64_t bits) { - return (__atomic_store_n(target, bits, __ATOMIC_RELAXED)); + return (__atomic_store_n(target, bits, __ATOMIC_RELEASE)); } #endif @@ -390,11 +390,11 @@ membar_sync(void) void membar_producer(void) { - __atomic_thread_fence(__ATOMIC_RELEASE); + __atomic_thread_fence(__ATOMIC_SEQ_CST); } void membar_consumer(void) { - __atomic_thread_fence(__ATOMIC_ACQUIRE); + __atomic_thread_fence(__ATOMIC_SEQ_CST); } diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 2c1d21edf19d..872b105328ce 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -101,3 +101,44 @@ libspl_sys_dktpdir = $(libspl_sysdir)/dktp libspl_sys_dktp_HEADERS = \ %D%/sys/dktp/fdisk.h +if BUILD_MACOS + +# macOS does not promote header location (legacy) +libsplmacosdir = $(includedir)/libspl/os/macos +libsplmacos_HEADERS = \ + %D%/os/macos/dirent.h \ + %D%/os/macos/libdiskmgt.h \ + %D%/os/macos/mntent.h \ + %D%/os/macos/poll.h \ + %D%/os/macos/pthread.h \ + %D%/os/macos/stdio.h \ + %D%/os/macos/stdlib.h \ + %D%/os/macos/string.h \ + %D%/os/macos/synch.h \ + %D%/os/macos/time.h \ + %D%/os/macos/unistd.h + +libsplmacos_machdir = $(libsplmacosdir)/mach +libsplmacos_mach_HEADERS = \ + %D%/os/macos/mach/boolean.h \ + %D%/os/macos/mach/task.h + +libsplmacos_sysdir = $(libsplmacosdir)/sys +libsplmacos_sys_HEADERS = \ + %D%/os/macos/sys/byteorder.h \ + %D%/os/macos/sys/errno.h \ + %D%/os/macos/sys/fcntl.h \ + %D%/os/macos/sys/file.h \ + %D%/os/macos/sys/kernel_types.h \ + %D%/os/macos/sys/misc.h \ + %D%/os/macos/sys/mnttab.h \ + %D%/os/macos/sys/mount.h \ + %D%/os/macos/sys/param.h \ + %D%/os/macos/sys/stat.h \ + %D%/os/macos/sys/sysmacros.h \ + %D%/os/macos/sys/time.h \ + %D%/os/macos/sys/uio.h \ + %D%/os/macos/sys/vfs.h \ + %D%/os/macos/sys/xattr.h \ + %D%/os/macos/sys/zfs_context_os.h +endif diff --git a/lib/libspl/include/sys/asm_linkage.h b/lib/libspl/include/sys/asm_linkage.h index 84aa0854a9ff..ba08164c954a 100644 --- a/lib/libspl/include/sys/asm_linkage.h +++ b/lib/libspl/include/sys/asm_linkage.h @@ -29,8 +29,11 @@ #if defined(__i386) || defined(__amd64) +#if defined(__APPLE__) +#include /* XX64 x86/sys/asm_linkage.h */ +#else #include /* XX64 x86/sys/asm_linkage.h */ - +#endif #endif #if defined(_KERNEL) && defined(HAVE_KERNEL_OBJTOOL) diff --git a/lib/libspl/include/sys/dkio.h b/lib/libspl/include/sys/dkio.h index 9517b580bdf5..72e9eeeb71f8 100644 --- a/lib/libspl/include/sys/dkio.h +++ b/lib/libspl/include/sys/dkio.h @@ -161,7 +161,9 @@ struct dk_geom { */ #define DKIOCGGEOM (DKIOC|1) /* Get geometry */ #define DKIOCINFO (DKIOC|3) /* Get info */ +#ifndef DKIOCEJECT #define DKIOCEJECT (DKIOC|6) /* Generic 'eject' */ +#endif #define DKIOCGVTOC (DKIOC|11) /* Get VTOC */ #define DKIOCSVTOC (DKIOC|12) /* Set VTOC & Write to Disk */ diff --git a/lib/libspl/include/sys/isa_defs.h b/lib/libspl/include/sys/isa_defs.h index 302f31e989cb..4b3fbe56318e 100644 --- a/lib/libspl/include/sys/isa_defs.h +++ b/lib/libspl/include/sys/isa_defs.h @@ -128,13 +128,16 @@ extern "C" { /* arm arch specific defines */ #elif defined(__arm) || defined(__arm__) +/* We can NOT define __arm / __arm__ on macOS, it is only for 32bit */ #if !defined(__arm) #define __arm #endif +#ifndef __APPLE__ #if !defined(__arm__) #define __arm__ #endif +#endif #if !defined(_ILP32) #define _ILP32 diff --git a/lib/libspl/include/sys/simd.h b/lib/libspl/include/sys/simd.h index 41f9df506468..3b14d554c9c4 100644 --- a/lib/libspl/include/sys/simd.h +++ b/lib/libspl/include/sys/simd.h @@ -49,6 +49,27 @@ static inline unsigned long getauxval(unsigned long key) #define AT_HWCAP 16 #define AT_HWCAP2 26 extern unsigned long getauxval(unsigned long type); +#elif defined(__APPLE__) +#include +#define AT_HWCAP 0 +static inline unsigned long getauxval(unsigned long key) +{ + (void) key; + /* HWCAP_ are all defined halfway down this file */ + unsigned long val = 1 /* HWCAP_FP */; + int intval; + size_t intvallen = sizeof (intval); + int err; + err = sysctlbyname("hw.optional.arm.FEAT_SHA256", + &intval, &intvallen, NULL, 0); + if (err == 0 && intval != 0) + val |= 0x00000040; /* SHA256 */ + err = sysctlbyname("hw.optional.arm.FEAT_SHA512", + &intval, &intvallen, NULL, 0); + if (err == 0 && intval != 0) + val |= 0x00200000; /* SHA512 */ + return (val); +} #endif /* __linux__ */ #endif /* arm || aarch64 || powerpc */ @@ -516,6 +537,7 @@ zfs_sha256_available(void) #define kfpu_end() do {} while (0) #define HWCAP_FP 0x00000001 +#define HWCAP_AES 0x00000008 #define HWCAP_SHA2 0x00000040 #define HWCAP_SHA512 0x00200000 @@ -549,6 +571,16 @@ zfs_sha512_available(void) return (hwcap & HWCAP_SHA512); } +/* + * Check if AESV8 is available + */ +static inline boolean_t +zfs_aesv8_available(void) +{ + unsigned long hwcap = getauxval(AT_HWCAP); + return (hwcap & HWCAP_AES); +} + #elif defined(__powerpc__) #define kfpu_allowed() 0 diff --git a/lib/libspl/include/sys/uio.h b/lib/libspl/include/sys/uio.h index e9e21819d4f8..94088a5cf4fb 100644 --- a/lib/libspl/include/sys/uio.h +++ b/lib/libspl/include/sys/uio.h @@ -43,14 +43,10 @@ #include #include_next -#ifdef __APPLE__ -#include -#endif - #include typedef struct iovec iovec_t; -#if defined(__linux__) || defined(__APPLE__) +#if defined(__linux__) typedef enum zfs_uio_rw { UIO_READ = 0, UIO_WRITE = 1, diff --git a/lib/libuutil/Makefile.am b/lib/libuutil/Makefile.am index b973ce3cca4c..18ecc74144c1 100644 --- a/lib/libuutil/Makefile.am +++ b/lib/libuutil/Makefile.am @@ -19,9 +19,11 @@ libuutil_la_LIBADD += $(LTLIBINTL) libuutil_la_LDFLAGS = -pthread +if !BUILD_MACOS if !ASAN_ENABLED libuutil_la_LDFLAGS += -Wl,-z,defs endif +endif libuutil_la_LDFLAGS += -version-info 3:0:0 diff --git a/lib/libzfs/Makefile.am b/lib/libzfs/Makefile.am index 5e74d908de3d..697da3a30c87 100644 --- a/lib/libzfs/Makefile.am +++ b/lib/libzfs/Makefile.am @@ -33,6 +33,15 @@ dist_libzfs_la_SOURCES += \ %D%/os/linux/libzfs_util_os.c endif +if BUILD_MACOS +dist_libzfs_la_SOURCES += \ + %D%/os/macos/libzfs_dataset_os.c \ + %D%/os/macos/libzfs_getmntany.c \ + %D%/os/macos/libzfs_mount_os.c \ + %D%/os/macos/libzfs_pool_os.c \ + %D%/os/macos/libzfs_util_os.c +endif + nodist_libzfs_la_SOURCES = \ module/zcommon/cityhash.c \ module/zcommon/zfeature_common.c \ @@ -61,14 +70,22 @@ libzfs_la_LIBADD += -lrt -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LIBFETCH_LIBS) $(L libzfs_la_LDFLAGS = -pthread +if !BUILD_MACOS if !ASAN_ENABLED libzfs_la_LDFLAGS += -Wl,-z,defs endif +endif if BUILD_FREEBSD libzfs_la_LIBADD += -lutil -lgeom endif +if BUILD_MACOS +libzfs_la_LIBADD += \ + libdiskmgt.la +libzfs_la_LDFLAGS += -lobjc -framework IOKit -framework Foundation -lssl +endif + libzfs_la_LDFLAGS += -version-info 5:0:1 pkgconfig_DATA += %D%/libzfs.pc diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 6e53bcb41a87..a2eb37f653f6 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -1862,7 +1862,12 @@ - + + + + + + diff --git a/lib/libzfs/libzfs_crypto.c b/lib/libzfs/libzfs_crypto.c index 8f2a50d55e87..8dd842dd6c27 100644 --- a/lib/libzfs/libzfs_crypto.c +++ b/lib/libzfs/libzfs_crypto.c @@ -611,7 +611,9 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri, (void) unlink(path); free(path); +#ifdef O_TMPFILE kfdok: +#endif if ((key = fdopen(kfd, "r+")) == NULL) { ret = errno; (void) close(kfd); diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 11d3eb6a3c60..0d9e320f5939 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -33,6 +33,7 @@ * Copyright (c) 2019 Datto Inc. * Copyright (c) 2019, loli10K * Copyright (c) 2021 Matt Fiddaman + * Copyright (c) 2020, Jorgen Lundman */ #include @@ -2207,6 +2208,18 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, mntopt_off = MNTOPT_NONBMAND; break; +#ifdef __APPLE__ /* So they don't need to have MNTOPT_BROWSE */ + case ZFS_PROP_BROWSE: + mntopt_on = MNTOPT_BROWSE; + mntopt_off = MNTOPT_NOBROWSE; + break; + + case ZFS_PROP_IGNOREOWNER: + mntopt_on = MNTOPT_NOOWNERS; + mntopt_off = MNTOPT_OWNERS; + break; +#endif + default: break; } @@ -2243,6 +2256,10 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, case ZFS_PROP_SETUID: #ifndef __FreeBSD__ case ZFS_PROP_XATTR: +#endif +#ifdef __APPLE__ + case ZFS_PROP_BROWSE: + case ZFS_PROP_IGNOREOWNER: #endif case ZFS_PROP_NBMAND: *val = getprop_uint64(zhp, prop, source); @@ -2753,6 +2770,33 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, relpath[0] != '\0')) str++; +#ifdef __APPLE__ + /* + * On OSX by default we mount pools under /Volumes + * unless the dataset property mountpoint specifies + * otherwise. + * In addition to this, there is an undocumented + * environment variable __ZFS_MAIN_MOUNTPOINT_DIR, + * used mainly by the testing environment, as it + * expects "/" by default. + */ + const char *default_mountpoint; + default_mountpoint = + getenv("__ZFS_MAIN_MOUNTPOINT_DIR"); + if (!default_mountpoint) + default_mountpoint = "/Volumes/"; + + if (relpath[0] == '\0') + (void) snprintf(propbuf, proplen, "%s%s", + root, str); + else + (void) snprintf(propbuf, proplen, "%s%s%s%s", + root, str, source == NULL || + source[0] == '\0' ? default_mountpoint : + "/", relpath); + +#else + if (relpath[0] == '\0') (void) snprintf(propbuf, proplen, "%s%s", root, str); @@ -2760,6 +2804,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, (void) snprintf(propbuf, proplen, "%s%s%s%s", root, str, relpath[0] == '@' ? "" : "/", relpath); +#endif /* APPLE */ + } else { /* 'legacy' or 'none' */ (void) strlcpy(propbuf, str, proplen); @@ -3899,7 +3945,23 @@ zfs_destroy(zfs_handle_t *zhp, boolean_t defer) error = lzc_destroy_snaps(nv, defer, NULL); fnvlist_free(nv); } else { + +#ifdef __APPLE__ + /* DiskArbitrationd gets in the way a lot */ + int retry = 0; + do { + if ((retry++) != 1) { + sleep(1); + } +#endif + error = lzc_destroy(zhp->zfs_name); + +#ifdef __APPLE__ + } while ((error == EBUSY) && (retry <= 5)); +#endif + + } if (error != 0 && error != ENOENT) { diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c index da2b26ef99ce..4b743bc593aa 100644 --- a/lib/libzfs/libzfs_diff.c +++ b/lib/libzfs/libzfs_diff.c @@ -761,7 +761,12 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, return (-1); } +#if defined(__APPLE__) + /* Can't do IO on pipes, open fds mkfifo */ + if (libzfs_macos_pipefd(&pipefd[0], &pipefd[1])) { +#else if (pipe2(pipefd, O_CLOEXEC)) { +#endif zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); teardown_differ_info(&di); return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf)); diff --git a/lib/libzfs/libzfs_iter.c b/lib/libzfs/libzfs_iter.c index 452d8fd6ab71..e1404475a3c1 100644 --- a/lib/libzfs/libzfs_iter.c +++ b/lib/libzfs/libzfs_iter.c @@ -634,17 +634,19 @@ zfs_iter_mounted(zfs_handle_t *zhp, zfs_iter_f func, void *data) continue; if ((mtab_zhp = zfs_open(zhp->zfs_hdl, entry.mnt_special, - ZFS_TYPE_FILESYSTEM)) == NULL) + ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT)) == NULL) continue; /* Ignore legacy mounts as they are user managed */ - verify(zfs_prop_get(mtab_zhp, ZFS_PROP_MOUNTPOINT, mnt_prop, - sizeof (mnt_prop), NULL, NULL, 0, B_FALSE) == 0); - if (strcmp(mnt_prop, "legacy") == 0) { - zfs_close(mtab_zhp); - continue; + if (mtab_zhp->zfs_type != ZFS_TYPE_SNAPSHOT) { + verify(zfs_prop_get(mtab_zhp, ZFS_PROP_MOUNTPOINT, + mnt_prop, sizeof (mnt_prop), NULL, NULL, 0, + B_FALSE) == 0); + if (strcmp(mnt_prop, "legacy") == 0) { + zfs_close(mtab_zhp); + continue; + } } - err = func(mtab_zhp, data); } diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index e9bc78aa8d39..ba2becec0186 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -1252,6 +1252,12 @@ dump_snapshot(zfs_handle_t *zhp, void *arg) } if (!sdd->dryrun) { + +#if defined(__APPLE__) + /* Can't do IO on pipes, possibly wrap fd in domain socket */ + libzfs_macos_wrapfd(&sdd->outfd, B_TRUE); +#endif + /* * If progress reporting is requested, spawn a new thread to * poll ZFS_IOC_SEND_PROGRESS at a regular interval. @@ -1961,6 +1967,11 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags, SEND_PROGRESS_THREAD_PARENT_BLOCK(&oldmask); } +#if defined(__APPLE__) + /* Can't do IO on pipes, possibly wrap fd in domain socket */ + libzfs_macos_wrapfd(&outfd, B_TRUE); +#endif + error = lzc_send_resume_redacted(zhp->zfs_name, fromname, outfd, lzc_flags, resumeobj, resumeoff, redact_book); if (redact_book != NULL) @@ -2747,6 +2758,11 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd, if (flags->dryrun) return (0); +#if defined(__APPLE__) + /* Can't do IO on pipes, possibly wrap fd in domain socket */ + libzfs_macos_wrapfd(&fd, B_TRUE); +#endif + /* * If progress reporting is requested, spawn a new thread to poll * ZFS_IOC_SEND_PROGRESS at a regular interval. @@ -2830,6 +2846,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd, return (zfs_standard_error(hdl, errno, errbuf)); } } + return (err != 0); } @@ -5019,6 +5036,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, goto out; } +#if defined(__APPLE__) + /* Can't do IO on pipes, possibly wrap fd in domain socket */ + libzfs_macos_wrapfd(&infd, B_FALSE); +#endif + if (flags->heal) { err = ioctl_err = lzc_receive_with_heal(destsnap, rcvprops, oxprops, wkeydata, wkeylen, origin, flags->force, @@ -5448,6 +5470,11 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, return (zfs_error(hdl, EZFS_NOENT, errbuf)); } +#if defined(__APPLE__) + /* Can't do IO on pipes, possibly wrap fd in domain socket */ + libzfs_macos_wrapfd(&infd, B_FALSE); +#endif + /* read in the BEGIN record */ if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE, &zcksum))) diff --git a/lib/libzfs_core/Makefile.am b/lib/libzfs_core/Makefile.am index d1c6fb86d186..e392e34f767d 100644 --- a/lib/libzfs_core/Makefile.am +++ b/lib/libzfs_core/Makefile.am @@ -23,6 +23,13 @@ nodist_libzfs_core_la_SOURCES = \ module/os/freebsd/zfs/zfs_ioctl_compat.c endif +if BUILD_MACOS +libzfs_core_la_CPPFLAGS += -I$(top_srcdir)/include/os/macos/zfs + +libzfs_core_la_SOURCES += \ + %D%/os/macos/libzfs_core_ioctl.c +endif + libzfs_core_la_LIBADD = \ libnvpair.la \ libspl.la @@ -31,9 +38,11 @@ libzfs_core_la_LIBADD += $(LTLIBINTL) libzfs_core_la_LDFLAGS = -pthread +if !BUILD_MACOS if !ASAN_ENABLED libzfs_core_la_LDFLAGS += -Wl,-z,defs endif +endif if BUILD_FREEBSD libzfs_core_la_LIBADD += -lutil -lgeom diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index c63a16de5ab6..17344e8f263f 100644 --- a/lib/libzfs_core/libzfs_core.c +++ b/lib/libzfs_core/libzfs_core.c @@ -94,6 +94,9 @@ #if __FreeBSD__ #define BIG_PIPE_SIZE (64 * 1024) /* From sys/pipe.h */ #endif +#if __APPLE__ +#define BIG_PIPE_SIZE (64 * 1024) +#endif static int g_fd = -1; static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/lib/libzfsbootenv/Makefile.am b/lib/libzfsbootenv/Makefile.am index 118f154821fc..8913f07983aa 100644 --- a/lib/libzfsbootenv/Makefile.am +++ b/lib/libzfsbootenv/Makefile.am @@ -18,9 +18,11 @@ libzfsbootenv_la_LIBADD = \ libzfsbootenv_la_LDFLAGS = +if !BUILD_MACOS if !ASAN_ENABLED libzfsbootenv_la_LDFLAGS += -Wl,-z,defs endif +endif libzfsbootenv_la_LDFLAGS += -version-info 1:0:0 diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 58d7f07527aa..4ef6d4b87bbb 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -197,9 +197,11 @@ libzpool_la_LIBADD += $(LIBCLOCK_GETTIME) $(ZLIB_LIBS) -ldl -lm libzpool_la_LDFLAGS = -pthread +if !BUILD_MACOS if !ASAN_ENABLED libzpool_la_LDFLAGS += -Wl,-z,defs endif +endif if BUILD_FREEBSD libzpool_la_LIBADD += -lgeom diff --git a/lib/libzutil/Makefile.am b/lib/libzutil/Makefile.am index 519906235f7f..cbd0363279a7 100644 --- a/lib/libzutil/Makefile.am +++ b/lib/libzutil/Makefile.am @@ -28,6 +28,12 @@ libzutil_la_SOURCES += \ %D%/os/freebsd/zutil_import_os.c endif +if BUILD_MACOS +libzutil_la_SOURCES += \ + %D%/os/macos/zutil_device_path_os.c \ + %D%/os/macos/zutil_import_os.c +endif + libzutil_la_LIBADD = \ libavl.la \ libtpool.la \ @@ -40,4 +46,9 @@ libzutil_la_LIBADD += \ -lrt endif +if BUILD_MACOS +libzutil_la_LIBADD += \ + libefi.la +endif + libzutil_la_LIBADD += -lm $(LIBBLKID_LIBS) $(LIBUDEV_LIBS) diff --git a/lib/libzutil/zutil_device_path.c b/lib/libzutil/zutil_device_path.c index 0425018e1022..4447f4af86c7 100644 --- a/lib/libzutil/zutil_device_path.c +++ b/lib/libzutil/zutil_device_path.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -158,6 +159,8 @@ zfs_strcmp_pathname(const char *name, const char *cmp, int wholedisk) char path_name[MAXPATHLEN]; char cmp_name[MAXPATHLEN]; char *dir, *tmp = NULL; + char *d, *b; + const char *dpath, *bname; /* Strip redundant slashes if they exist due to ZPOOL_IMPORT_PATH */ cmp_name[0] = '\0'; @@ -182,8 +185,39 @@ zfs_strcmp_pathname(const char *name, const char *cmp, int wholedisk) return (ENOMEM); } - if ((path_len != cmp_len) || strcmp(path_name, cmp_name)) - return (ENOENT); + if ((path_len == cmp_len) && strcmp(path_name, cmp_name) == 0) + return (0); + else { + int idx; + d = strdup(path_name); + b = strdup(path_name); + idx = zfs_dirnamelen(d); + if (idx != -1) + d[idx] = 0; + dpath = d; + bname = zfs_basename(b); + if (realpath(dpath, path_name) == NULL) { + (void) fprintf(stderr, "cannot resolve path '%s'\n", + dpath); + free(d); + free(b); + return (ENOENT); + } + + if (strcmp(dpath, path_name) == 0) { + free(d); + free(b); + return (ENOENT); // We already tried this path + } + + strlcat(path_name, "/", sizeof (path_name)); + path_len = strlcat(path_name, bname, sizeof (path_name)); + free(d); + free(b); + + if ((path_len == cmp_len) && strcmp(path_name, cmp_name) == 0) + return (0); + } - return (0); + return (ENOENT); } diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index 19d8a4742813..15a1c9a4c178 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -910,6 +910,12 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok, return (NULL); } +#ifdef __APPLE__ + +/* We have our own zpool_read_label() / label_offset() */ + +#else + /* * Return the offset of the given label. */ @@ -921,6 +927,9 @@ label_offset(uint64_t size, int l) 0 : size - VDEV_LABELS * sizeof (vdev_label_t))); } +#ifdef __APPLE__ +/* We have our own */ +#else /* * The same description applies as to zpool_read_label below, * except here we do it without aio, presumably because an aio call @@ -997,6 +1006,7 @@ zpool_read_label_slow(int fd, nvlist_t **config, int *num_labels) return (0); } +#endif /* APPLE */ /* * Given a file descriptor, read the label information and return an nvlist @@ -1133,6 +1143,7 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels) return (0); #endif } +#endif /* APPLE */ /* * Sorted by full path and then vdev guid to allow for multiple entries with @@ -1239,6 +1250,12 @@ zpool_find_import_scan_add_slice(libpc_handle_t *hdl, pthread_mutex_t *lock, slice->rn_lock = lock; slice->rn_avl = cache; slice->rn_hdl = hdl; +#ifdef __APPLE__ + /* Prefer diskX over rdiskX: involve os/ somehow? */ + if (name[0] == 'r') + slice->rn_order = order + IMPORT_ORDER_DEFAULT; + else +#endif slice->rn_order = order + IMPORT_ORDER_SCAN_OFFSET; slice->rn_labelpaths = B_FALSE; diff --git a/lib/libzutil/zutil_pool.c b/lib/libzutil/zutil_pool.c index 288a0033cd13..c3383442961c 100644 --- a/lib/libzutil/zutil_pool.c +++ b/lib/libzutil/zutil_pool.c @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/man/man7/zfsprops-macos.7 b/man/man7/zfsprops-macos.7 new file mode 100644 index 000000000000..639a1a4e21b4 --- /dev/null +++ b/man/man7/zfsprops-macos.7 @@ -0,0 +1,95 @@ +.\" +.\" 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) 2009 Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2011 Joshua M. Clulow +.\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. +.\" Copyright (c) 2011, Pawel Jakub Dawidek +.\" Copyright (c) 2012, Glen Barber +.\" Copyright (c) 2012, Bryan Drewery +.\" Copyright (c) 2013, Steven Hartland +.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved. +.\" Copyright (c) 2014, Joyent, Inc. All rights reserved. +.\" Copyright (c) 2014 by Adam Stevko. All rights reserved. +.\" Copyright (c) 2014 Integros [integros.com] +.\" Copyright (c) 2016 Nexenta Systems, Inc. All Rights Reserved. +.\" Copyright (c) 2014, Xin LI +.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved. +.\" Copyright 2019 Richard Laager. All rights reserved. +.\" Copyright 2018 Nexenta Systems, Inc. +.\" Copyright 2019 Joyent, Inc. +.\" Copyright (c) 2019, Kjeld Schouten-Lebbing +.\" +.Dd April 29, 2021 +.Dt ZFSPROPS-MACOS 7 +.Os +. +.Sh NAME +.Nm zfsprops-macos +.Nd native properties of ZFS datasets specific to macOS +. +.Sh DESCRIPTION +These properties are like the native properties described in +.Xr zfsprops 8 +but they are specific to macOS. +.Pp +The following native properties can be used to change the behavior of a ZFS +dataset. +.Bl -tag -width "" +.It Xo +.Sy com.apple.browse Ns = Ns Sy on Ns | Ns Sy off +.Xc +Equivalent to mount option +.Sy browse/nobrowse . +This option indicates +that the mount point should not be visible via the GUI (i.e., appear +on the Desktop as a separate volume). Setting it to off will result +in Spotlight being unavailable for the specified mount point. +The default value is +.Sy off . +.It Xo +.Sy com.apple.ignoreowner Ns = Ns Sy on Ns | Ns Sy off +.Xc +Equivalent to mount option +.Sy noowners . +Ignore the ownership field for the entire volume. +The default value is +.Sy off . +.It Xo +.Sy com.apple.mimic Ns = Ns Sy hfs Ns | Ns Sy off +.Xc +Some applications check if the filesystem type is "hfs" and refuse to work with +ZFS. +In this situation, this property can be enabled and the filesystem type will be +reported as "hfs". +The default value is +.Sy off . +.It Xo +.Sy com.apple.devdisk Ns = Ns Sy poolonly Ns | Ns Sy on Ns | Ns Sy off +.Xc +Create a /dev/diskX pseudo-disk for the mount, which has better compatibility +with macOS UI. +Due to the cost of creating a /dev/disk entry, the default value is set to +.Sy poolonly +as to only create an entry for the pool's root dataset. +For lower datasets, set to +.Sy on . +.El diff --git a/module/Kbuild.in b/module/Kbuild.in index c132171592a8..946184dff78b 100644 --- a/module/Kbuild.in +++ b/module/Kbuild.in @@ -151,6 +151,7 @@ ICP_OBJS_ARM := \ asm-arm/sha2/sha512-armv7.o ICP_OBJS_ARM64 := \ + asm-aarch64/aes/aes_aesv8.o \ asm-aarch64/blake3/b3_aarch64_sse2.o \ asm-aarch64/blake3/b3_aarch64_sse41.o \ asm-aarch64/sha2/sha256-armv8.o \ diff --git a/module/Makefile.bsd b/module/Makefile.bsd index 0c4d8bfe1159..55341a50a16b 100644 --- a/module/Makefile.bsd +++ b/module/Makefile.bsd @@ -15,6 +15,7 @@ KMOD= openzfs ${SRCDIR}/icp/algs/blake3 \ ${SRCDIR}/icp/algs/edonr \ ${SRCDIR}/icp/algs/sha2 \ + ${SRCDIR}/icp/asm-aarch64/aes \ ${SRCDIR}/icp/asm-aarch64/blake3 \ ${SRCDIR}/icp/asm-aarch64/sha2 \ ${SRCDIR}/icp/asm-arm/sha2 \ @@ -88,6 +89,9 @@ SRCS+= avl.c # icp SRCS+= edonr.c +#icp/asm-aarch64/aes +SRCS+= aesv8-armx.S + #icp/algs/blake3 SRCS+= blake3.c \ blake3_generic.c \ diff --git a/module/Makefile.in b/module/Makefile.in index 5b71e1abf79e..19aa259aa968 100644 --- a/module/Makefile.in +++ b/module/Makefile.in @@ -10,13 +10,15 @@ uninstall: modules_uninstall data_uninstall check: .PHONY: all distclean maintainer-clean install uninstall check distdir \ - modules modules-Linux modules-FreeBSD modules-unknown \ - clean clean-Linux clean-FreeBSD \ + modules modules-Linux modules-FreeBSD modules-macOS modules-unknown \ + clean clean-Linux clean-FreeBSD clean-macOS \ modules_install modules_install-Linux modules_install-FreeBSD \ - data_install data_install-Linux data_install-FreeBSD \ + modules_install-macOS data_install data_install-Linux \ + data_install-FreeBSD data_install-macOS \ modules_uninstall modules_uninstall-Linux modules_uninstall-FreeBSD \ - data_uninstall data_uninstall-Linux data_uninstall-FreeBSD \ - cppcheck cppcheck-Linux cppcheck-FreeBSD + modules_uninstall-macOS data_uninstall data_uninstall-Linux \ + data_uninstall-FreeBSD data_uninstall-macOS \ + cppcheck cppcheck-Linux cppcheck-FreeBSD cppcheck-macOS # For FreeBSD, use debug options from ./configure if not overridden. export WITH_DEBUG ?= @WITH_DEBUG@ @@ -60,6 +62,9 @@ modules-Linux: modules-FreeBSD: +$(FMAKE) +modules-macOS: + @true + modules-unknown: @true @@ -76,6 +81,9 @@ clean-Linux: clean-FreeBSD: +$(FMAKE) clean +clean-macOS: + @true + clean: clean-@ac_system@ .PHONY: modules_uninstall-Linux-legacy @@ -110,6 +118,9 @@ modules_install-FreeBSD: @# Install the kernel modules +$(FMAKE) install +modules_install-macOS: + @true + modules_install: modules_install-@ac_system@ data_install-Linux: @@ -119,6 +130,9 @@ data_install-Linux: data_install-FreeBSD: @ +data_install-macOS: + @ + data_install: data_install-@ac_system@ modules_uninstall-Linux: modules_uninstall-Linux-legacy @@ -128,6 +142,9 @@ modules_uninstall-Linux: modules_uninstall-Linux-legacy modules_uninstall-FreeBSD: @false +modules_uninstall-macOS: + @false + modules_uninstall: modules_uninstall-@ac_system@ data_uninstall-Linux: @@ -136,6 +153,9 @@ data_uninstall-Linux: data_uninstall-FreeBSD: @ +data_uninstall-macOS: + @ + data_uninstall: data_uninstall-@ac_system@ cppcheck-Linux: @@ -158,6 +178,9 @@ cppcheck-Linux: cppcheck-FreeBSD: @true +cppcheck-macOS: + @true + cppcheck: cppcheck-@ac_system@ distdir: diff --git a/module/icp/algs/aes/aes_impl.c b/module/icp/algs/aes/aes_impl.c index 9daa975226fe..db0c84940630 100644 --- a/module/icp/algs/aes/aes_impl.c +++ b/module/icp/algs/aes/aes_impl.c @@ -233,6 +233,9 @@ static const aes_impl_ops_t *aes_all_impl[] = { #if defined(__x86_64) && defined(HAVE_AES) &aes_aesni_impl, #endif +#if defined(__aarch64__) && defined(HAVE_AESV8) + &aes_aesv8_impl, +#endif }; /* Indicate that benchmark has been completed */ @@ -307,12 +310,21 @@ aes_impl_init(void) if (curr_impl->is_supported()) aes_supp_impl[c++] = (aes_impl_ops_t *)curr_impl; } + aes_supp_impl_cnt = c; /* * Set the fastest implementation given the assumption that the * hardware accelerated version is the fastest. */ +#if defined(__aarch64__) +#if defined(HAVE_AESV8) + if (aes_aesv8_impl.is_supported()) { + memcpy(&aes_fastest_impl, &aes_aesv8_impl, + sizeof (aes_fastest_impl)); + } else +#endif +#endif #if defined(__x86_64) #if defined(HAVE_AES) if (aes_aesni_impl.is_supported()) { @@ -334,6 +346,7 @@ aes_impl_init(void) /* Finish initialization */ atomic_swap_32(&icp_aes_impl, user_sel_impl); aes_impl_initialized = B_TRUE; + } static const struct { @@ -404,14 +417,17 @@ aes_impl_set(const char *val) return (err); } -#if defined(_KERNEL) && defined(__linux__) +#if defined(_KERNEL) +#if defined(__linux__) static int icp_aes_impl_set(const char *val, zfs_kernel_param_t *kp) { return (aes_impl_set(val)); } +#endif +#if defined(__linux__) || defined(__APPLE__) static int icp_aes_impl_get(char *buffer, zfs_kernel_param_t *kp) { @@ -437,6 +453,28 @@ icp_aes_impl_get(char *buffer, zfs_kernel_param_t *kp) return (cnt); } +#endif /* defined(Linux) || defined(APPLE) */ + +#if defined(__APPLE__) +/* get / set function */ +int +param_icp_aes_impl_set(ZFS_MODULE_PARAM_ARGS) +{ + char buf[1024]; /* Linux module string limit */ + int rc = 0; + + /* Always fill in value before calling sysctl_handle_*() */ + if (req->newptr == (user_addr_t)NULL) + (void) icp_aes_impl_get(buf, NULL); + + rc = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (rc || req->newptr == (user_addr_t)NULL) + return (rc); + + rc = aes_impl_set(buf); + return (rc); +} +#endif /* defined(APPLE) */ module_param_call(icp_aes_impl, icp_aes_impl_set, icp_aes_impl_get, NULL, 0644); diff --git a/module/icp/algs/aes/aes_impl_aesv8.c b/module/icp/algs/aes/aes_impl_aesv8.c new file mode 100644 index 000000000000..b389f9975150 --- /dev/null +++ b/module/icp/algs/aes/aes_impl_aesv8.c @@ -0,0 +1,146 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2023, Jorgen Lundman + */ + +#define HAVE_AESV8 +#if defined(__aarch64__) && defined(HAVE_AESV8) + +#include +#include +#include + +/* These functions are used to execute AES-V8 instructions: */ +#ifdef OPENSSL_INTERFACE +extern ASMABI int aes_v8_set_encrypt_key(const unsigned char *userKey, + const int bits, AES_KEY *key); +extern ASMABI int aes_v8_set_decrypt_key(const unsigned char *userKey, + const int bits, AES_KEY *key); +extern ASMABI void aes_v8_encrypt(const unsigned char *in, + unsigned char *out, const AES_KEY *key, const unsigned int nround); +extern ASMABI void aes_v8_decrypt(const unsigned char *in, + unsigned char *out, const AES_KEY *key, const unsigned int nround); +#endif + +extern ASMABI int aes_v8_set_encrypt_key(const uint32_t rk[], + uint64_t bits, const uint32_t cipherKey[]); +extern ASMABI int aes_v8_set_decrypt_key(const uint32_t rk[], + uint64_t bits, const uint32_t cipherKey[]); +/* nround $10 (128), $12 (192), $14 (256) */ +extern ASMABI void aes_v8_encrypt(const uint32_t pt[4], + const uint32_t ct[4], const uint32_t rk[], const unsigned int nround); +extern ASMABI void aes_v8_decrypt(const uint32_t ct[4], + const uint32_t pt[4], const uint32_t rk[], const unsigned int nround); + +#define AES_MAXNR 14 +typedef struct aes_key_st { + unsigned int rd_key[4 *(AES_MAXNR + 1)]; + int rounds; + unsigned int pad[3]; +} AES_KEY; + +#include + +/* + * Expand the 32-bit AES cipher key array into the encryption and decryption + * key schedules. + * + * Parameters: + * key AES key schedule to be initialized + * keyarr32 User key + * keyBits AES key size (128, 192, or 256 bits) + */ +static void +aes_aesv8_generate(aes_key_t *key, const uint32_t *keyarr32, int keybits) +{ + kfpu_begin(); + key->nr = aes_v8_set_encrypt_key(keyarr32, keybits, + &(key->encr_ks.ks32[0])); + key->nr = aes_v8_set_decrypt_key(keyarr32, keybits, + &(key->decr_ks.ks32[0])); + kfpu_end(); +} + +/* + * Encrypt one block of data. The block is assumed to be an array + * of four uint32_t values, so copy for alignment (and byte-order + * reversal for little endian systems might be necessary on the + * input and output byte streams. + * The size of the key schedule depends on the number of rounds + * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk Key schedule, of aes_ks_t (60 32-bit integers) + * Nr Number of rounds + * pt Input block (plain text) + * ct Output block (crypto text). Can overlap with pt + */ +static void +aes_aesv8_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4], + uint32_t ct[4]) +{ + kfpu_begin(); + aes_v8_encrypt(pt, ct, rk, Nr); + kfpu_end(); +} + +/* + * Decrypt one block of data. The block is assumed to be an array + * of four uint32_t values, so copy for alignment (and byte-order + * reversal for little endian systems might be necessary on the + * input and output byte streams. + * The size of the key schedule depends on the number of rounds + * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk Key schedule, of aes_ks_t (60 32-bit integers) + * Nr Number of rounds + * ct Input block (crypto text) + * pt Output block (plain text). Can overlap with pt + */ +static void +aes_aesv8_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4], + uint32_t pt[4]) +{ + kfpu_begin(); + aes_v8_encrypt(ct, pt, rk, Nr); + kfpu_end(); +} + +static boolean_t +aes_aesv8_will_work(void) +{ + return (kfpu_allowed() && zfs_aesv8_available()); + +} + +const aes_impl_ops_t aes_aesv8_impl = { + .generate = &aes_aesv8_generate, + .encrypt = &aes_aesv8_encrypt, + .decrypt = &aes_aesv8_decrypt, + .is_supported = &aes_aesv8_will_work, + .needs_byteswap = B_FALSE, + .name = "aesv8" +}; + +#endif /* defined(__aarch64__) && defined(HAVE_AESV8) */ diff --git a/module/icp/algs/blake3/blake3_impl.c b/module/icp/algs/blake3/blake3_impl.c index f3f48c2dfa1a..238ca68a2a93 100644 --- a/module/icp/algs/blake3/blake3_impl.c +++ b/module/icp/algs/blake3/blake3_impl.c @@ -30,6 +30,13 @@ #include "blake3_impl.h" +#if defined(__APPLE__) && defined(__aarch64__) +/* Sadly, toolchain sets this, but M1 can't compile it as-is */ +#undef __aarch64__ +#undef HAVE_SSE2 +#undef HAVE_SSE4_1 +#endif + #if defined(__aarch64__) || \ (defined(__x86_64) && defined(HAVE_SSE2)) || \ (defined(__PPC64__) && defined(__LITTLE_ENDIAN__)) @@ -347,7 +354,7 @@ blake3_param_set(const char *val, zfs_kernel_param_t *unused) return (generic_impl_setname(val)); } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__APPLE__) #include @@ -357,7 +364,7 @@ blake3_param(ZFS_MODULE_PARAM_ARGS) int err; generic_impl_init(); - if (req->newptr == NULL) { + if ((void *)req->newptr == NULL) { const uint32_t impl = IMPL_READ(generic_impl_chosen); const int init_buflen = 64; const char *fmt; @@ -379,7 +386,12 @@ blake3_param(ZFS_MODULE_PARAM_ARGS) (void) sbuf_printf(s, fmt, generic_supp_impls[i]->name); } +#ifdef __APPLE__ + err = SYSCTL_OUT(req, s->s_buf, s->s_len); + sbuf_finish(s); +#else err = sbuf_finish(s); +#endif sbuf_delete(s); return (err); diff --git a/module/icp/algs/modes/gcm.c b/module/icp/algs/modes/gcm.c index dd8db6f97460..e10e2738748f 100644 --- a/module/icp/algs/modes/gcm.c +++ b/module/icp/algs/modes/gcm.c @@ -862,6 +862,12 @@ gcm_impl_init(void) * Set the fastest implementation given the assumption that the * hardware accelerated version is the fastest. */ +#if defined(__aarch64__) && defined(HAVE_ARMV8) + if (gcm_armv8_impl.is_supported()) { + memcpy(&gcm_fastest_impl, &gcm_armv8_impl, + sizeof (gcm_fastest_impl)); + } else +#endif #if defined(__x86_64) && defined(HAVE_PCLMULQDQ) if (gcm_pclmulqdq_impl.is_supported()) { memcpy(&gcm_fastest_impl, &gcm_pclmulqdq_impl, @@ -883,7 +889,13 @@ gcm_impl_init(void) if (gcm_avx_will_work()) { #ifdef HAVE_MOVBE if (zfs_movbe_available() == B_TRUE) { +#ifdef __APPLE__ + atomic_swap_32( + (volatile unsigned int *)&gcm_avx_can_use_movbe, + B_TRUE); +#else atomic_swap_32(&gcm_avx_can_use_movbe, B_TRUE); +#endif } #endif if (GCM_IMPL_READ(user_sel_impl) == IMPL_FASTEST) { @@ -985,14 +997,17 @@ gcm_impl_set(const char *val) return (err); } -#if defined(_KERNEL) && defined(__linux__) +#if defined(_KERNEL) +#if defined(__linux__) static int icp_gcm_impl_set(const char *val, zfs_kernel_param_t *kp) { return (gcm_impl_set(val)); } +#endif +#if defined(__linux__) || defined(__APPLE__) static int icp_gcm_impl_get(char *buffer, zfs_kernel_param_t *kp) { @@ -1024,6 +1039,28 @@ icp_gcm_impl_get(char *buffer, zfs_kernel_param_t *kp) return (cnt); } +#endif /* defined(Linux) || defined(APPLE) */ + +#if defined(__APPLE__) +/* get / set function */ +int +param_icp_gcm_impl_set(ZFS_MODULE_PARAM_ARGS) +{ + char buf[1024]; /* Linux module string limit */ + int rc = 0; + + /* Always fill in value before calling sysctl_handle_*() */ + if (req->newptr == (user_addr_t)NULL) + (void) icp_gcm_impl_get(buf, NULL); + + rc = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (rc || req->newptr == (user_addr_t)NULL) + return (rc); + + rc = gcm_impl_set(buf); + return (rc); +} +#endif /* defined(APPLE) */ module_param_call(icp_gcm_impl, icp_gcm_impl_set, icp_gcm_impl_get, NULL, 0644); @@ -1092,7 +1129,11 @@ static inline void gcm_set_avx(boolean_t val) { if (gcm_avx_will_work() == B_TRUE) { +#ifdef __APPLE__ + atomic_swap_32((volatile unsigned int *)&gcm_use_avx, val); +#else atomic_swap_32(&gcm_use_avx, val); +#endif } } @@ -1543,6 +1584,8 @@ gcm_init_avx(gcm_ctx_t *ctx, const uint8_t *iv, size_t iv_len, } #if defined(_KERNEL) + +#if defined(__linux__) static int icp_gcm_avx_set_chunk_size(const char *buf, zfs_kernel_param_t *kp) { @@ -1563,6 +1606,38 @@ icp_gcm_avx_set_chunk_size(const char *buf, zfs_kernel_param_t *kp) error = param_set_uint(val_rounded, kp); return (error); } +#endif + +#ifdef __APPLE__ +/* Lives in here to have access to GCM macros */ +int +param_icp_gcm_avx_set_chunk_size(ZFS_MODULE_PARAM_ARGS) +{ + unsigned long val; + char buf[16]; + int rc = 0; + + /* Always fill in value before calling sysctl_handle_*() */ + if (req->newptr == (user_addr_t)NULL) + snprintf(buf, sizeof (buf), "%u", gcm_avx_chunk_size); + + rc = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (rc || req->newptr == (user_addr_t)NULL) + return (rc); + + rc = kstrtoul(buf, 0, &val); + if (rc) + return (rc); + + val = (val / GCM_AVX_MIN_DECRYPT_BYTES) * GCM_AVX_MIN_DECRYPT_BYTES; + + if (val < GCM_AVX_MIN_ENCRYPT_BYTES || val > GCM_AVX_MAX_CHUNK_SIZE) + return (EINVAL); + + gcm_avx_chunk_size = val; + return (rc); +} +#endif module_param_call(icp_gcm_avx_chunk_size, icp_gcm_avx_set_chunk_size, param_get_uint, &gcm_avx_chunk_size, 0644); diff --git a/module/icp/algs/sha2/sha256_impl.c b/module/icp/algs/sha2/sha256_impl.c index 01ce5cbd814c..4759aa6547ca 100644 --- a/module/icp/algs/sha2/sha256_impl.c +++ b/module/icp/algs/sha2/sha256_impl.c @@ -250,7 +250,7 @@ sha256_param_set(const char *val, zfs_kernel_param_t *unused) return (generic_impl_setname(val)); } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__APPLE__) #include @@ -260,7 +260,7 @@ sha256_param(ZFS_MODULE_PARAM_ARGS) int err; generic_impl_init(); - if (req->newptr == NULL) { + if ((void *)req->newptr == NULL) { const uint32_t impl = IMPL_READ(generic_impl_chosen); const int init_buflen = 64; const char *fmt; @@ -282,7 +282,12 @@ sha256_param(ZFS_MODULE_PARAM_ARGS) (void) sbuf_printf(s, fmt, generic_supp_impls[i]->name); } +#ifdef __APPLE__ + err = SYSCTL_OUT(req, s->s_buf, s->s_len); + sbuf_finish(s); +#else err = sbuf_finish(s); +#endif sbuf_delete(s); return (err); diff --git a/module/icp/algs/sha2/sha512_impl.c b/module/icp/algs/sha2/sha512_impl.c index 27b35a639a54..f7ad1af6bc2c 100644 --- a/module/icp/algs/sha2/sha512_impl.c +++ b/module/icp/algs/sha2/sha512_impl.c @@ -225,7 +225,7 @@ sha512_param_set(const char *val, zfs_kernel_param_t *unused) return (generic_impl_setname(val)); } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__APPLE__) #include @@ -235,7 +235,7 @@ sha512_param(ZFS_MODULE_PARAM_ARGS) int err; generic_impl_init(); - if (req->newptr == NULL) { + if ((void *)req->newptr == NULL) { const uint32_t impl = IMPL_READ(generic_impl_chosen); const int init_buflen = 64; const char *fmt; @@ -257,7 +257,12 @@ sha512_param(ZFS_MODULE_PARAM_ARGS) (void) sbuf_printf(s, fmt, generic_supp_impls[i]->name); } +#ifdef __APPLE__ + err = SYSCTL_OUT(req, s->s_buf, s->s_len); + sbuf_finish(s); +#else err = sbuf_finish(s); +#endif sbuf_delete(s); return (err); diff --git a/module/icp/asm-aarch64/aes/aesv8-armx.S b/module/icp/asm-aarch64/aes/aesv8-armx.S new file mode 100644 index 000000000000..f26bf08e778e --- /dev/null +++ b/module/icp/asm-aarch64/aes/aesv8-armx.S @@ -0,0 +1,3245 @@ +/* + * ==================================================================== + * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. + * + * 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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 + +#if defined(__aarch64__) + +/* + * + * OpenSSL interface: + * int intel_AES_set_encrypt_key(const unsigned char *userKey, + * const int bits, AES_KEY *key) ; + * int intel_AES_set_decrypt_key(const unsigned char *userKey, + * const int bits, AES_KEY *key) ; + * Return values for above are non-zero on error, 0 on success. + * + * void intel_AES_encrypt(const unsigned char *in, unsigned char *out, + * const AES_KEY *key) ; + * void intel_AES_decrypt(const unsigned char *in, unsigned char *out, + * const AES_KEY *key) ; + * typedef struct aes_key_st { + * unsigned int rd_key[4 *(AES_MAXNR + 1)] ; + * int rounds ; + * unsigned int pad[3] ; + * } AES_KEY ; + * + * 2023/03/17 lundman + * changed to use 4th parameter for NROUNDS + * __AARCH64EB__ for big endian + * + * Make it return Nrounds, delete other methods xts, etc + */ + +SECTION_TEXT +.balign 32 +Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +ENTRY_ALIGN(aes_v8_set_encrypt_key, 32) +Lenc_key: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq Lenc_key_abort + cmp x2,#0 + b.eq Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt Lenc_key_abort + cmp w1,#256 + b.gt Lenc_key_abort + tst w1,#0x3f + b.ne Lenc_key_abort + + adr x3,Lrcon + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt Loop128 + b.eq L192 + b L256 + +.balign 16 +Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 +#ifndef OPENSSL_INTERFACE + mov x3,#10 // Return nround +#endif + b Ldone + +.balign 16 +L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 +#ifdef __AARCH64EB__ + st1 {v4.4s},[x2],#16 + sub x2,x2,#8 +#else + st1 {v4.8b},[x2],#8 +#endif + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne Loop192 + + mov w12,#12 + add x2,x2,#0x20 +#ifndef OPENSSL_INTERFACE + mov x3,#12 // Return nround +#endif + b Ldone + +.balign 16 +L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 +#ifndef OPENSSL_INTERFACE + mov x3,#14 // Return nround +#endif + b.eq Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b Loop256 + +Ldone: + str w12,[x2] +#ifdef OPENSSL_INTERFACE + mov x3,#0 // return value, skip with openzfs +#endif + +Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret + + +ENTRY_ALIGN(aes_v8_set_decrypt_key, 32) + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl Lenc_key + + cmp x0,#0 + b.ne Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +Ldec_key_abort: + ldp x29,x30,[sp],#16 + ret + +ENTRY_ALIGN(aes_v8_encrypt, 32) +#ifdef OPENSSL_INTERFACE + ldr w3,[x2,#240] // NumRounds in AESKEY +#endif + // We'll pass numRounds in 4th argument instead, ie x3/w3. + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret + +ENTRY_ALIGN(aes_v8_decrypt, 32) +#ifdef OPENSSL_INTERFACE + ldr w3,[x2,#240] // NumRounds in AESKEY +#endif + // We'll pass numRounds in 4th argument instead, ie x3/w3. + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret + +ENTRY_ALIGN(aes_v8_ecb_encrypt, 32) + subs x2,x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne Lecb_big_size + ld1 {v0.16b},[x0] + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + ld1 {v5.4s,v6.4s},[x3],#32 // load key schedule... + + b.eq Lecb_small_dec + aese v0.16b,v5.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v6.16b + aesmc v0.16b,v0.16b + subs w5,w5,#10 // if rounds==10, jump to aes-128-ecb processing + b.eq Lecb_128_enc +Lecb_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt Lecb_round_loop +Lecb_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b Lecb_Final_abort +Lecb_small_dec: + aesd v0.16b,v5.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v6.16b + aesimc v0.16b,v0.16b + subs w5,w5,#10 // bias + b.eq Lecb_128_dec +Lecb_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt Lecb_dec_round_loop +Lecb_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b Lecb_Final_abort +Lecb_big_size: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x8,#16 + b.lo Lecb_done + csel x8,xzr,x8,eq + + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq Lecb_dec + + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo Lecb_enc_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo Loop3x_ecb_enc + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +Loop5x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop5x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + cmp x2,#0x40 // because Lecb_enc_tail4x + sub x2,x2,#0x50 + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lecb_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,Lecb_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_ecb_enc + + add x2,x2,#0x50 + cbz x2,Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo Lecb_enc_tail + + b Loop3x_ecb_enc + +.align 4 +Lecb_enc_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b Lecb_done +.align 4 +Loop3x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs Loop3x_ecb_enc + + cmn x2,#0x30 + b.eq Lecb_done + nop + +Lecb_enc_tail: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lecb_enc_tail + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq Lecb_enc_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b Lecb_done + +Lecb_enc_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + b Lecb_done +.balign 32 +Lecb_dec: + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo Lecb_dec_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo Loop3x_ecb_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +Loop5x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop5x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because Lecb_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lecb_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,Lecb_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_ecb_dec + + add x2,x2,#0x50 + cbz x2,Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo Lecb_dec_tail + + b Loop3x_ecb_dec + +.balign 16 +Lecb_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b Lecb_done +.balign 16 +Loop3x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs Loop3x_ecb_dec + + cmn x2,#0x30 + b.eq Lecb_done + nop + +Lecb_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lecb_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq Lecb_dec_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b Lecb_done + +Lecb_dec_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + +Lecb_done: + ldr x29,[sp],#16 +Lecb_Final_abort: + ret + +ENTRY_ALIGN(aes_v8_cbc_encrypt, 32) + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq Lcbc_enc128 + + ld1 {v2.4s,v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b Lenter_cbc_enc + +.balign 16 +Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b Lcbc_done + +.balign 32 +Lcbc_enc128: + ld1 {v2.4s,v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b Lenter_cbc_enc128 +Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b Lcbc_done +.balign 32 +Lcbc_dec: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + b.lo Lcbc_dec_tail + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v27.16b,v24.16b,v24.16b + cmp x2,#32 + b.lo Loop3x_cbc_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + orr v28.16b,v25.16b,v25.16b + orr v29.16b,v26.16b,v26.16b + +Loop5x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop5x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because Lcbc_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lcbc_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v6.16b,v7.16b + aesd v0.16b,v23.16b + eor v5.16b,v2.16b,v7.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + eor v17.16b,v3.16b,v7.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + eor v30.16b,v27.16b,v7.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + eor v31.16b,v28.16b,v7.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + orr v6.16b,v29.16b,v29.16b + ld1 {v29.16b},[x0],#16 + cbz x6,Lcbc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v5.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v17.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v30.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_cbc_dec + + add x2,x2,#0x50 + cbz x2,Lcbc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v2.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v3.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + orr v27.16b,v29.16b,v29.16b + b.lo Lcbc_dec_tail + + b Loop3x_cbc_dec + +.balign 16 +Lcbc_tail4x: + eor v5.16b,v4.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + eor v30.16b,v30.16b,v25.16b + eor v31.16b,v31.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b Lcbc_done +.balign 16 +Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + orr v6.16b,v27.16b,v27.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq Lcbc_done + nop + +Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b Lcbc_done + +Lcbc_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + +Lcbc_done: + st1 {v6.16b},[x4] +Lcbc_abort: + ldr x29,[sp],#16 + ret + +ENTRY_ALIGN(aes_v8_ctr32_encrypt_blocks, 32) + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] +#ifdef __AARCH64EB__ + ld1 {v0.16b},[x4] +#else + ld1 {v0.4s},[x4] +#endif + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo +#ifndef __AARCH64EB__ + rev w8, w8 +#endif + orr v1.16b,v0.16b,v0.16b + add w10, w8, #1 + orr v18.16b,v0.16b,v0.16b + add w8, w8, #2 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v1.s[3],w10 + b.ls Lctr32_tail + rev w12, w8 + sub x2,x2,#3 // bias + mov v18.s[3],w12 + cmp x2,#32 + b.lo Loop3x_ctr32 + + add w13,w8,#1 + add w14,w8,#2 + orr v24.16b,v0.16b,v0.16b + rev w13,w13 + orr v25.16b,v0.16b,v0.16b + rev w14,w14 + mov v24.s[3],w13 + sub x2,x2,#2 // bias + mov v25.s[3],w14 + add w8,w8,#2 + b Loop5x_ctr32 + +.balign 16 +Loop5x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop5x_ctr32 + + mov x7,x3 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + add w9,w8,#1 + add w10,w8,#2 + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + add w12,w8,#3 + add w13,w8,#4 + aese v18.16b,v20.16b + aesmc v18.16b,v18.16b + add w14,w8,#5 + rev w9,w9 + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + rev w10,w10 + rev w12,w12 + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + rev w13,w13 + rev w14,w14 + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v18.16b,v21.16b + aesmc v18.16b,v18.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0],#16 + aese v18.16b,v22.16b + aesmc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v26.16b},[x0],#16 + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + ld1 {v27.16b},[x0],#16 + + aese v0.16b,v23.16b + eor v2.16b,v2.16b,v7.16b + aese v1.16b,v23.16b + eor v3.16b,v3.16b,v7.16b + aese v18.16b,v23.16b + eor v19.16b,v19.16b,v7.16b + aese v24.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + aese v25.16b,v23.16b + eor v27.16b,v27.16b,v7.16b + + eor v2.16b,v2.16b,v0.16b + orr v0.16b,v6.16b,v6.16b + eor v3.16b,v3.16b,v1.16b + orr v1.16b,v6.16b,v6.16b + eor v19.16b,v19.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + eor v26.16b,v26.16b,v24.16b + orr v24.16b,v6.16b,v6.16b + eor v27.16b,v27.16b,v25.16b + orr v25.16b,v6.16b,v6.16b + + st1 {v2.16b},[x1],#16 + mov v0.s[3],w9 + st1 {v3.16b},[x1],#16 + mov v1.s[3],w10 + st1 {v19.16b},[x1],#16 + mov v18.s[3],w12 + st1 {v26.16b},[x1],#16 + mov v24.s[3],w13 + st1 {v27.16b},[x1],#16 + mov v25.s[3],w14 + + mov w6,w5 + cbz x2,Lctr32_done + + add w8,w8,#5 + subs x2,x2,#5 + b.hs Loop5x_ctr32 + + add x2,x2,#5 + sub w8,w8,#5 + + cmp x2,#2 + mov x12,#16 + csel x12,xzr,x12,lo + b.ls Lctr32_tail + + sub x2,x2,#3 // bias + add w8,w8,#3 + b Loop3x_ctr32 + +.balign 16 +Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + orr v0.16b,v6.16b,v6.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + orr v1.16b,v6.16b,v6.16b + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + add w9,w8,#1 + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + eor v19.16b,v19.16b,v7.16b + rev w9,w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + mov v0.s[3], w9 + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + mov v1.s[3], w10 + rev w12,w8 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + mov v18.s[3], w12 + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs Loop3x_ctr32 + + adds x2,x2,#3 + b.eq Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq Lctr32_done + st1 {v3.16b},[x1] + +Lctr32_done: + ldr x29,[sp],#16 + ret + +ENTRY_ALIGN(aes_v8_xts_encrypt, 32) + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne Lxts_enc_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +Loop_enc_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_enc_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aese v0.16b,v28.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v29.16b + aesmc v0.16b,v0.16b + subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing + b.eq Lxts_128_enc +Lxts_enc_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt Lxts_enc_round_loop +Lxts_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1] + b Lxts_enc_final_abort + +.balign 16 +Lxts_enc_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + // tailcnt store the tail value of length%16. + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo Lxts_abort + csel x8,xzr,x8,eq + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +Loop_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // next starting point + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + + // Encryption +Lxts_enc: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo Lxts_inner_enc_tail + eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv + eor v24.16b,v24.16b,v8.16b + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // the third block + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo Lxts_outer_enc_tail + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + + ld1 {v25.16b},[x0],#16 + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b Loop5x_xts_enc + +.balign 16 +Loop5x_xts_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt Loop5x_xts_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + subs x2,x2,#0x50 // because Lxts_enc_tail4x + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lxts_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aese v0.16b,v23.16b + // The iv for first block of one iteration + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,Lxts_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_xts_enc + + + // If left 4 blocks, borrow the five block's processing. + cmn x2,#0x10 + b.ne Loop5x_enc_after + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq Loop5x_xts_enc + +Loop5x_enc_after: + add x2,x2,#0x50 + cbz x2,Lxts_enc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo Lxts_inner_enc_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b Lxts_outer_enc_tail + +.balign 16 +Lxts_enc_tail4x: + add x0,x0,#16 + eor v5.16b,v1.16b,v5.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b Lxts_enc_done +.balign 16 +Lxts_outer_enc_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_outer_enc_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + //mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + + add x6,x6,#0x20 + add x0,x0,x6 + mov x7,x3 + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + add w6,w5,#2 + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + cmn x2,#0x30 + b.eq Lxts_enc_done +Lxts_encxor_one: + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +Lxts_inner_enc_tail: + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq Lxts_enc_tail_loop + eor v24.16b,v29.16b,v6.16b +Lxts_enc_tail_loop: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_enc_tail_loop + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq Lxts_enc_one + eor v5.16b,v5.16b,v1.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + st1 {v17.16b},[x1],#16 + fmov x9,d8 + fmov x10,v8.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b Lxts_enc_done + +Lxts_enc_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v6.16b,v6.16b + st1 {v5.16b},[x1],#16 + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b Lxts_enc_done +.balign 32 +Lxts_enc_done: + // Process the tail block with cipher stealing. + tst x21,#0xf + b.eq Lxts_abort + + mov x20,x0 + mov x13,x1 + sub x1,x1,#16 +.composite_enc_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_enc_loop +Lxts_enc_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Encrypt the composite block to get the last second encrypted text block + ldr w6,[x3,#240] // load key schedule... + ld1 {v0.16b},[x3],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x3],#16 // load key schedule... +Loop_final_enc: + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 + subs w6,w6,#2 + aese v26.16b,v1.16b + aesmc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 + b.gt Loop_final_enc + + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aese v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +Lxts_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 +Lxts_enc_final_abort: + ret + +ENTRY_ALIGN(aes_v8_xts_decrypt, 32) + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne Lxts_dec_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +Loop_dec_small_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_dec_small_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aesd v0.16b,v28.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v29.16b + aesimc v0.16b,v0.16b + subs w6,w6,#10 // bias + b.eq Lxts_128_dec +Lxts_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt Lxts_dec_round_loop +Lxts_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v6.16b,v0.16b + st1 {v0.16b},[x1] + b Lxts_dec_final_abort +Lxts_dec_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo Lxts_dec_abort + + // Encrypt the iv with key2, as the first XEX iv + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +Loop_dec_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_dec_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // load rounds number + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule... + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + + add x7,x3,#32 + mov w6,w5 + b Lxts_dec + + // Decryption +.balign 32 +Lxts_dec: + tst x21,#0xf + b.eq Lxts_dec_begin + subs x2,x2,#16 + csel x8,xzr,x8,eq + ld1 {v0.16b},[x0],#16 + b.lo Lxts_done + sub x0,x0,#16 +Lxts_dec_begin: + ld1 {v0.16b},[x0],x8 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + ld1 {v24.16b},[x0],#16 + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo Lxts_inner_dec_tail + eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv + eor v24.16b,v24.16b,v8.16b + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // third block xox with third iv + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo Lxts_outer_dec_tail + + ld1 {v25.16b},[x0],#16 + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b Loop5x_xts_dec + +.balign 16 +Loop5x_xts_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 // load key schedule... + b.gt Loop5x_xts_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + subs x2,x2,#0x50 // because Lxts_dec_tail4x + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lxts_dec_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aesd v0.16b,v23.16b + // The iv for first block of next iteration. + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,Lxts_dec_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_xts_dec + + cmn x2,#0x10 + b.ne Loop5x_dec_after + // If x2(x2) equal to -0x10, the left blocks is 4. + // After specially processing, utilize the five blocks processing again. + // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq Loop5x_xts_dec + +Loop5x_dec_after: + add x2,x2,#0x50 + cbz x2,Lxts_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo Lxts_inner_dec_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b Lxts_outer_dec_tail + +.balign 16 +Lxts_dec_tail4x: + add x0,x0,#16 + ld1 {v0.4s},[x0],#16 + eor v5.16b,v1.16b,v4.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b Lxts_done +.balign 16 +Lxts_outer_dec_tail: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_outer_dec_tail + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + add x6,x6,#0x20 + add x0,x0,x6 // x0 is adjusted to the last data + + mov x7,x3 + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + + cmn x2,#0x30 + add x2,x2,#0x30 + b.eq Lxts_done + sub x2,x2,#0x30 + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +Lxts_inner_dec_tail: + // x2 == -0x10 means two blocks left. + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq Lxts_dec_tail_loop + eor v24.16b,v29.16b,v6.16b +Lxts_dec_tail_loop: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_dec_tail_loop + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq Lxts_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v9.16b,v9.16b + orr v8.16b,v10.16b,v10.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + add x2,x2,#16 + b Lxts_done + +Lxts_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + orr v8.16b,v9.16b,v9.16b + st1 {v5.16b},[x1],#16 + add x2,x2,#32 + +Lxts_done: + tst x21,#0xf + b.eq Lxts_dec_abort + // Processing the last two blocks with cipher stealing. + mov x7,x3 + cbnz x2,Lxts_dec_1st_done + ld1 {v0.4s},[x0],#16 + + // Decrypt the last second block to get the last plain text block +Lxts_dec_1st_done: + eor v26.16b,v0.16b,v8.16b + ldr w6,[x3,#240] + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 +Loop_final_2nd_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 // load key schedule... + b.gt Loop_final_2nd_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v8.16b + st1 {v26.16b},[x1] + + mov x20,x0 + add x13,x1,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_dec_loop +Lxts_dec_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Decrypt the composite block to get the last second plain text block + ldr w6,[x7,#240] + ld1 {v0.16b},[x7],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x7],#16 +Loop_final_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x7],#16 // load key schedule... + b.gt Loop_final_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +Lxts_dec_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 + +Lxts_dec_final_abort: + ret + +#endif diff --git a/module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S b/module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S index dc2719d142db..91399aeb28e3 100644 --- a/module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S +++ b/module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S @@ -33,7 +33,9 @@ #if defined(__aarch64__) .text +#ifndef __APPLE__ .section .note.gnu.property,"a",@note +#endif .p2align 3 .word 4 .word 16 @@ -47,7 +49,9 @@ .text .globl zfs_blake3_compress_in_place_sse2 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_compress_in_place_sse2,@function +#endif zfs_blake3_compress_in_place_sse2: .cfi_startproc hint #25 @@ -79,17 +83,24 @@ zfs_blake3_compress_in_place_sse2: hint #29 ret .Lfunc_end0: - .size zfs_blake3_compress_in_place_sse2, .Lfunc_end0-zfs_blake3_compress_in_place_sse2 +#ifndef __APPLE__ +.size zfs_blake3_compress_in_place_sse2, .Lfunc_end0-zfs_blake3_compress_in_place_sse2 +#endif .cfi_endproc + +#ifndef __APPLE__ .section .rodata.cst16,"aM",@progbits,16 +#endif .p2align 4 .LCPI1_0: .xword -4942790177982912921 .xword -6534734903820487822 .text .p2align 2 +#ifndef __APPLE__ .type compress_pre,@function +#endif compress_pre: .cfi_startproc hint #34 @@ -97,10 +108,18 @@ compress_pre: movi d0, #0x0000ff000000ff ldr q2, [x1] fmov d3, x4 +#ifndef __APPLE__ adrp x8, .LCPI1_0 +#else + adrp x8, .LCPI1_0@PAGE +#endif mov v1.s[1], w5 str q2, [x0] +#ifndef __APPLE__ ldr q4, [x8, :lo12:.LCPI1_0] +#else + ldr q4, [x8, :lo12:.LCPI1_0@PAGEOFF] +#endif add x8, x2, #32 ldr q5, [x1, #16] and v0.8b, v1.8b, v0.8b @@ -546,12 +565,16 @@ compress_pre: stp q0, q1, [x0] ret .Lfunc_end1: +#ifndef __APPLE__ .size compress_pre, .Lfunc_end1-compress_pre +#endif .cfi_endproc .globl zfs_blake3_compress_xof_sse2 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_compress_xof_sse2,@function +#endif zfs_blake3_compress_xof_sse2: .cfi_startproc hint #25 @@ -591,10 +614,14 @@ zfs_blake3_compress_xof_sse2: hint #29 ret .Lfunc_end2: +#ifndef __APPLE__ .size zfs_blake3_compress_xof_sse2, .Lfunc_end2-zfs_blake3_compress_xof_sse2 +#endif .cfi_endproc +#ifndef __APPLE__ .section .rodata.cst16,"aM",@progbits,16 +#endif .p2align 4 .LCPI3_0: .word 0 @@ -604,7 +631,9 @@ zfs_blake3_compress_xof_sse2: .text .globl zfs_blake3_hash_many_sse2 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_hash_many_sse2,@function +#endif zfs_blake3_hash_many_sse2: .cfi_startproc hint #25 @@ -650,13 +679,21 @@ zfs_blake3_hash_many_sse2: cmp x1, #4 str x3, [sp, #40] b.lo .LBB3_6 +#ifndef __APPLE__ adrp x8, .LCPI3_0 +#else + adrp x8, .LCPI3_0@PAGE +#endif sbfx w9, w5, #0, #1 mov w10, #44677 mov w11, #62322 movk w10, #47975, lsl #16 movk w11, #15470, lsl #16 +#ifndef __APPLE__ ldr q0, [x8, :lo12:.LCPI3_0] +#else + ldr q0, [x8, :lo12:.LCPI3_0@PAGEOFF] +#endif dup v1.4s, w9 mov w9, #58983 orr w8, w7, w19 @@ -2055,7 +2092,11 @@ zfs_blake3_hash_many_sse2: hint #29 ret .Lfunc_end3: +#ifndef __APPLE__ .size zfs_blake3_hash_many_sse2, .Lfunc_end3-zfs_blake3_hash_many_sse2 +#endif .cfi_endproc +#ifndef __APPLE__ .section ".note.GNU-stack","",@progbits -#endif \ No newline at end of file +#endif +#endif diff --git a/module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S b/module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S index c4c2dfc5bcde..ee4638858286 100644 --- a/module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S +++ b/module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S @@ -33,7 +33,9 @@ #if defined(__aarch64__) .text +#ifndef __APPLE__ .section .note.gnu.property,"a",@note +#endif .p2align 3 .word 4 .word 16 @@ -47,7 +49,9 @@ .text .globl zfs_blake3_compress_in_place_sse41 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_compress_in_place_sse41,@function +#endif zfs_blake3_compress_in_place_sse41: .cfi_startproc hint #25 @@ -79,10 +83,14 @@ zfs_blake3_compress_in_place_sse41: hint #29 ret .Lfunc_end0: +#ifndef __APPLE__ .size zfs_blake3_compress_in_place_sse41, .Lfunc_end0-zfs_blake3_compress_in_place_sse41 +#endif .cfi_endproc +#ifndef __APPLE__ .section .rodata.cst16,"aM",@progbits,16 +#endif .p2align 4 .LCPI1_0: .xword -4942790177982912921 @@ -123,19 +131,33 @@ zfs_blake3_compress_in_place_sse41: .byte 12 .text .p2align 2 +#ifndef __APPLE__ .type compress_pre,@function +#endif compress_pre: .cfi_startproc hint #34 fmov s1, w3 movi d0, #0x0000ff000000ff ldr q2, [x1] +#ifndef __APPLE__ adrp x8, .LCPI1_0 +#else + adrp x8, .LCPI1_0@PAGE +#endif mov v1.s[1], w5 str q2, [x0] +#ifndef __APPLE__ ldr q4, [x8, :lo12:.LCPI1_0] +#else + ldr q4, [x8, :lo12:.LCPI1_0@PAGEOFF] +#endif ldr q5, [x1, #16] +#ifndef __APPLE__ adrp x8, .LCPI1_1 +#else + adrp x8, .LCPI1_1@PAGE +#endif and v0.8b, v1.8b, v0.8b fmov d1, x4 stp q5, q4, [x0, #16] @@ -146,8 +168,13 @@ compress_pre: add v0.4s, v2.4s, v3.4s uzp2 v2.4s, v6.4s, v7.4s add v16.4s, v0.4s, v5.4s +#ifndef __APPLE__ ldr q0, [x8, :lo12:.LCPI1_1] adrp x8, .LCPI1_2 +#else + ldr q0, [x8, :lo12:.LCPI1_1@PAGEOFF] + adrp x8, .LCPI1_2@PAGE +#endif eor v1.16b, v16.16b, v1.16b add v7.4s, v16.4s, v2.4s tbl v1.16b, { v1.16b }, v0.16b @@ -158,7 +185,11 @@ compress_pre: orr v5.16b, v5.16b, v6.16b add v6.4s, v7.4s, v5.4s eor v7.16b, v1.16b, v6.16b +#ifndef __APPLE__ ldr q1, [x8, :lo12:.LCPI1_2] +#else + ldr q1, [x8, :lo12:.LCPI1_2@PAGEOFF] +#endif add x8, x2, #32 tbl v7.16b, { v7.16b }, v1.16b ld2 { v16.4s, v17.4s }, [x8] @@ -556,12 +587,16 @@ compress_pre: stp q2, q3, [x0] ret .Lfunc_end1: +#ifndef __APPLE__ .size compress_pre, .Lfunc_end1-compress_pre +#endif .cfi_endproc .globl zfs_blake3_compress_xof_sse41 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_compress_xof_sse41,@function +#endif zfs_blake3_compress_xof_sse41: .cfi_startproc hint #25 @@ -601,10 +636,14 @@ zfs_blake3_compress_xof_sse41: hint #29 ret .Lfunc_end2: +#ifndef __APPLE__ .size zfs_blake3_compress_xof_sse41, .Lfunc_end2-zfs_blake3_compress_xof_sse41 +#endif .cfi_endproc +#ifndef __APPLE__ .section .rodata.cst16,"aM",@progbits,16 +#endif .p2align 4 .LCPI3_0: .word 0 @@ -653,7 +692,9 @@ zfs_blake3_compress_xof_sse41: .text .globl zfs_blake3_hash_many_sse41 .p2align 2 +#ifndef __APPLE__ .type zfs_blake3_hash_many_sse41,@function +#endif zfs_blake3_hash_many_sse41: .cfi_startproc hint #34 @@ -687,25 +728,45 @@ zfs_blake3_hash_many_sse41: .cfi_offset b14, -136 .cfi_offset b15, -144 ldr x8, [sp, #520] +#ifndef __APPLE__ adrp x11, .LCPI3_1 +#else + adrp x11, .LCPI3_1@PAGE +#endif ldrb w9, [sp, #512] +#ifndef __APPLE__ adrp x10, .LCPI3_2 +#else + adrp x10, .LCPI3_2@PAGE +#endif cmp x1, #4 b.lo .LBB3_6 +#ifndef __APPLE__ adrp x12, .LCPI3_0 +#else + adrp x12, .LCPI3_0@PAGE +#endif sbfx w13, w5, #0, #1 mov w15, #58983 mov w16, #44677 movk w15, #27145, lsl #16 movk w16, #47975, lsl #16 +#ifndef __APPLE__ ldr q0, [x12, :lo12:.LCPI3_0] +#else + ldr q0, [x12, :lo12:.LCPI3_0@PAGEOFF] +#endif dup v1.4s, w13 movi v13.4s, #64 mov w13, #62322 mov w14, #62778 orr w12, w7, w6 and v0.16b, v1.16b, v0.16b +#ifndef __APPLE__ ldr q1, [x11, :lo12:.LCPI3_1] +#else + ldr q1, [x11, :lo12:.LCPI3_1@PAGEOFF] +#endif movk w13, #15470, lsl #16 movk w14, #42319, lsl #16 dup v14.4s, w15 @@ -876,7 +937,11 @@ zfs_blake3_hash_many_sse41: ushr v8.4s, v25.4s, #12 shl v25.4s, v25.4s, #20 orr v3.16b, v20.16b, v18.16b +#ifndef __APPLE__ ldr q18, [x10, :lo12:.LCPI3_2] +#else + ldr q18, [x10, :lo12:.LCPI3_2@PAGEOFF] +#endif orr v13.16b, v17.16b, v26.16b orr v24.16b, v24.16b, v29.16b orr v14.16b, v25.16b, v8.16b @@ -1935,11 +2000,21 @@ zfs_blake3_hash_many_sse41: b .LBB3_2 .LBB3_6: cbz x1, .LBB3_14 +#ifndef __APPLE__ adrp x12, .LCPI3_3 ldr q0, [x11, :lo12:.LCPI3_1] +#else + adrp x12, .LCPI3_3@PAGE + ldr q0, [x11, :lo12:.LCPI3_1@PAGEOFF] +#endif orr w11, w7, w6 +#ifndef __APPLE__ ldr q2, [x10, :lo12:.LCPI3_2] ldr q1, [x12, :lo12:.LCPI3_3] +#else + ldr q2, [x10, :lo12:.LCPI3_2@PAGEOFF] + ldr q1, [x12, :lo12:.LCPI3_3@PAGEOFF] +#endif and x12, x5, #0x1 .LBB3_8: movi v3.4s, #64 @@ -2392,7 +2467,11 @@ zfs_blake3_hash_many_sse41: ldp d15, d14, [sp], #144 ret .Lfunc_end3: +#ifndef __APPLE__ .size zfs_blake3_hash_many_sse41, .Lfunc_end3-zfs_blake3_hash_many_sse41 +#endif .cfi_endproc +#ifndef __APPLE__ .section ".note.GNU-stack","",@progbits -#endif \ No newline at end of file +#endif +#endif diff --git a/module/icp/asm-aarch64/sha2/sha256-armv8.S b/module/icp/asm-aarch64/sha2/sha256-armv8.S index fa50c4e74d59..0992ab714f8d 100644 --- a/module/icp/asm-aarch64/sha2/sha256-armv8.S +++ b/module/icp/asm-aarch64/sha2/sha256-armv8.S @@ -19,12 +19,14 @@ * - modified assembly to fit into OpenZFS */ +#include + #if defined(__aarch64__) -.text +SECTION_TEXT -.align 6 -.type .LK256,%object +.balign 64 +SET_OBJ(.LK256) .LK256: .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 @@ -43,12 +45,9 @@ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 .long 0 //terminator -.size .LK256,.-.LK256 +SET_SIZE(.LK256) -.globl zfs_sha256_block_armv7 -.type zfs_sha256_block_armv7,%function -.align 6 -zfs_sha256_block_armv7: +ENTRY_ALIGN(zfs_sha256_block_armv7, 64) stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -1009,12 +1008,9 @@ zfs_sha256_block_armv7: ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 ret -.size zfs_sha256_block_armv7,.-zfs_sha256_block_armv7 +SET_SIZE(zfs_sha256_block_armv7) -.globl zfs_sha256_block_armv8 -.type zfs_sha256_block_armv8,%function -.align 6 -zfs_sha256_block_armv8: +ENTRY_ALIGN(zfs_sha256_block_armv8, 64) .Lv8_entry: stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -1149,12 +1145,9 @@ zfs_sha256_block_armv8: ldr x29,[sp],#16 ret -.size zfs_sha256_block_armv8,.-zfs_sha256_block_armv8 +SET_SIZE(zfs_sha256_block_armv8) -.globl zfs_sha256_block_neon -.type zfs_sha256_block_neon,%function -.align 4 -zfs_sha256_block_neon: +ENTRY_ALIGN(zfs_sha256_block_neon, 16) .Lneon_entry: stp x29, x30, [sp, #-16]! mov x29, sp @@ -1994,6 +1987,6 @@ zfs_sha256_block_neon: ldr x29,[x29] add sp,sp,#16*4+16 ret -.size zfs_sha256_block_neon,.-zfs_sha256_block_neon +SET_SIZE(zfs_sha256_block_neon) #endif diff --git a/module/icp/asm-aarch64/sha2/sha512-armv8.S b/module/icp/asm-aarch64/sha2/sha512-armv8.S index 1683fc1ca53c..5b530acca31f 100644 --- a/module/icp/asm-aarch64/sha2/sha512-armv8.S +++ b/module/icp/asm-aarch64/sha2/sha512-armv8.S @@ -18,13 +18,14 @@ * Portions Copyright (c) 2022 Tino Reichardt * - modified assembly to fit into OpenZFS */ +#include #if defined(__aarch64__) -.text +SECTION_TEXT -.align 6 -.type .LK512,%object +.balign 64 +SET_OBJ(.LK512) .LK512: .quad 0x428a2f98d728ae22,0x7137449123ef65cd .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc @@ -67,12 +68,9 @@ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 .quad 0 // terminator -.size .LK512,.-.LK512 +SET_SIZE(.LK512) -.globl zfs_sha512_block_armv7 -.type zfs_sha512_block_armv7,%function -.align 6 -zfs_sha512_block_armv7: +ENTRY_ALIGN(zfs_sha512_block_armv7, 64) stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -1033,13 +1031,10 @@ zfs_sha512_block_armv7: ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 ret -.size zfs_sha512_block_armv7,.-zfs_sha512_block_armv7 +SET_SIZE(zfs_sha512_block_armv7) -.globl zfs_sha512_block_armv8 -.type zfs_sha512_block_armv8,%function -.align 6 -zfs_sha512_block_armv8: +ENTRY_ALIGN(zfs_sha512_block_armv8, 64) .Lv8_entry: // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later stp x29,x30,[sp,#-16]! @@ -1061,7 +1056,7 @@ zfs_sha512_block_armv8: rev64 v23.16b,v23.16b b .Loop_hw -.align 4 +.balign 16 .Loop_hw: ld1 {v24.2d},[x3],#16 subs x2,x2,#1 @@ -1554,5 +1549,5 @@ zfs_sha512_block_armv8: ldr x29,[sp],#16 ret -.size zfs_sha512_block_armv8,.-zfs_sha512_block_armv8 +SET_SIZE(zfs_sha512_block_armv8) #endif diff --git a/module/icp/core/kcf_mech_tabs.c b/module/icp/core/kcf_mech_tabs.c index 41705e84bc4b..96c0c2cfa7fc 100644 --- a/module/icp/core/kcf_mech_tabs.c +++ b/module/icp/core/kcf_mech_tabs.c @@ -170,6 +170,7 @@ kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname) strlcpy(me_tab[i].me_name, mechname, CRYPTO_MAX_MECH_NAME); me_tab[i].me_mechid = KCF_MECHID(class, i); + me_tab[i].me_sw_prov = NULL; /* Add the new mechanism to the hash table */ avl_insert(&kcf_mech_hash, &me_tab[i], where); diff --git a/module/icp/include/aes/aes_impl.h b/module/icp/include/aes/aes_impl.h index 66eb4a6c8fb6..379a735b093c 100644 --- a/module/icp/include/aes/aes_impl.h +++ b/module/icp/include/aes/aes_impl.h @@ -203,6 +203,10 @@ extern ASMABI void aes_decrypt_amd64(const uint32_t rk[], int Nr, #if defined(__x86_64) && defined(HAVE_AES) extern const aes_impl_ops_t aes_aesni_impl; #endif +#define HAVE_AESV8 /* fix me, autoconf */ +#if defined(__aarch64__) && defined(HAVE_AESV8) +extern const aes_impl_ops_t aes_aesv8_impl; +#endif /* * Initializes fastest implementation diff --git a/module/lua/ldo.c b/module/lua/ldo.c index 38bd4e08a73d..b2c2c1e2dd8f 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -65,7 +65,7 @@ static intptr_t stack_remaining(void) { #ifdef _KERNEL -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #if defined(__i386__) #define JMP_BUF_CNT 6 #elif defined(__x86_64__) diff --git a/module/lua/setjmp/setjmp_aarch64.S b/module/lua/setjmp/setjmp_aarch64.S index 040ef1821ab0..201e580bed05 100644 --- a/module/lua/setjmp/setjmp_aarch64.S +++ b/module/lua/setjmp/setjmp_aarch64.S @@ -29,20 +29,10 @@ * */ +#include #ifdef __aarch64__ -#define ENTRY(sym) \ - .text; \ - .globl sym; \ - .balign 2; \ - .type sym,#function; \ -sym: - -#define END(sym) \ - .size sym, . - sym - - ENTRY(setjmp) /* Store the stack pointer */ mov x8, sp @@ -59,7 +49,7 @@ ENTRY(setjmp) /* Return value */ mov x0, #0 ret -END(setjmp) +SET_SIZE(setjmp) ENTRY(longjmp) /* Restore the stack pointer */ @@ -77,7 +67,7 @@ ENTRY(longjmp) /* Load the return value */ mov x0, x1 ret -END(longjmp) +SET_SIZE(longjmp) #ifdef __ELF__ .section .note.GNU-stack,"",%progbits diff --git a/module/nvpair/nvpair.c b/module/nvpair/nvpair.c index d9449e47e87a..e2a1cfbf1f65 100644 --- a/module/nvpair/nvpair.c +++ b/module/nvpair/nvpair.c @@ -3253,6 +3253,34 @@ nvs_xdr_nvp_##type(XDR *xdrs, void *ptr) \ return (xdr_##type(xdrs, ptr)); \ } +#elif defined(__APPLE__) && defined(_KERNEL) + +#define NVS_BUILD_XDRPROC_T(type) \ +static bool_t \ +nvs_xdr_nvp_##type(XDR *xdrs, void *ptr) \ +{ \ + return (xdr_##type(xdrs, ptr)); \ +} + +#elif defined(__APPLE__) && defined(_KERNEL) + +#define NVS_BUILD_XDRPROC_T(type) \ +static bool_t \ +nvs_xdr_nvp_##type(XDR *xdrs, void *ptr, ...) \ +{ \ + return (xdr_##type(xdrs, ptr)); \ +} + +#elif defined(__APPLE__) /* mac userland */ + +#define NVS_BUILD_XDRPROC_T(type) \ +static bool_t \ +nvs_xdr_nvp_##type(XDR *xdrs, void *ptr, \ + __unused unsigned int u) \ +{ \ + return (xdr_##type(xdrs, ptr)); \ +} + #elif !defined(_KERNEL) && defined(XDR_CONTROL) /* tirpc */ #define NVS_BUILD_XDRPROC_T(type) \ diff --git a/module/zcommon/zfeature_common.c b/module/zcommon/zfeature_common.c index 4c9b7ed72a0f..7696e62ddb76 100644 --- a/module/zcommon/zfeature_common.c +++ b/module/zcommon/zfeature_common.c @@ -175,7 +175,8 @@ struct zfs_mod_supported_features { struct zfs_mod_supported_features * zfs_mod_list_supported(const char *scope) { -#if defined(__FreeBSD__) || defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) +#if defined(__FreeBSD__) || defined(__APPLE__) || \ + defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) (void) scope; return (NULL); #else @@ -236,7 +237,8 @@ zfs_mod_list_supported(const char *scope) void zfs_mod_list_supported_free(struct zfs_mod_supported_features *list) { -#if !defined(__FreeBSD__) && !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD) +#if !defined(__FreeBSD__) && !defined(__APPLE__) && \ + !defined(_KERNEL) && !defined(LIB_ZPOOL_BUILD) if (list) { tdestroy(list->tree, free); free(list); @@ -310,7 +312,8 @@ zfs_mod_supported_feature(const char *name, * that all features are supported. */ -#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) || defined(__FreeBSD__) +#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) || \ + defined(__FreeBSD__) || defined(__APPLE__) (void) name, (void) sfeatures; return (B_TRUE); #else diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c index 619ddef0243a..a769fb3d8ab3 100644 --- a/module/zcommon/zfs_fletcher.c +++ b/module/zcommon/zfs_fletcher.c @@ -188,7 +188,7 @@ static const fletcher_4_ops_t *fletcher_4_impls[] = { #if defined(__x86_64) && defined(HAVE_AVX512BW) &fletcher_4_avx512bw_ops, #endif -#if defined(__aarch64__) && !defined(__FreeBSD__) +#if defined(__aarch64__) && !defined(__FreeBSD__) && !defined(__APPLE__) &fletcher_4_aarch64_neon_ops, #endif }; @@ -947,9 +947,9 @@ fletcher_4_param_set(const char *val, zfs_kernel_param_t *unused) static int fletcher_4_param(ZFS_MODULE_PARAM_ARGS) { - int err; + int err = 0; - if (req->newptr == NULL) { + if ((void *)req->newptr == NULL) { const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen); const int init_buflen = 64; const char *fmt; @@ -968,9 +968,13 @@ fletcher_4_param(ZFS_MODULE_PARAM_ARGS) fletcher_4_supp_impls[i]->name); } +#ifdef __APPLE__ + err = SYSCTL_OUT(req, s->s_buf, s->s_len); + sbuf_finish(s); +#else err = sbuf_finish(s); +#endif sbuf_delete(s); - return (err); } diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c index 3db6fd13f4ae..fa5e139b364d 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -391,6 +391,22 @@ zfs_prop_init(void) struct zfs_mod_supported_features *sfeatures = zfs_mod_list_supported(ZFS_SYSFS_DATASET_PROPERTIES); + /* __APPLE__ */ + static zprop_index_t devdisk_table[] = { + { "poolonly", ZFS_DEVDISK_POOLONLY }, + { "off", ZFS_DEVDISK_OFF }, + { "on", ZFS_DEVDISK_ON }, + { NULL } + }; + + static zprop_index_t mimic_table[] = { + { "off", ZFS_MIMIC_OFF }, + { "hfs", ZFS_MIMIC_HFS }, + { "apfs", ZFS_MIMIC_APFS }, + { NULL } + }; + /* __APPLE__ */ + /* inherit index properties */ zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata", ZFS_REDUNDANT_METADATA_ALL, @@ -598,6 +614,24 @@ zfs_prop_init(void) ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "[,...]", "RSNAPS", sfeatures); + /* __APPLE__ */ + zprop_register_index(ZFS_PROP_BROWSE, "com.apple.browse", 1, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off", + "COM.APPLE.BROWSE", boolean_table, sfeatures); + zprop_register_index(ZFS_PROP_IGNOREOWNER, "com.apple.ignoreowner", 0, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off", + "COM.APPLE.IGNOREOWNER", boolean_table, sfeatures); + zprop_register_hidden(ZFS_PROP_LASTUNMOUNT, "COM.APPLE.LASTUNMOUNT", + PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "LASTUNMOUNT", + B_FALSE, sfeatures); + zprop_register_index(ZFS_PROP_MIMIC, "com.apple.mimic", 0, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "off | hfs | apfs", + "COM.APPLE.MIMIC_HFS", mimic_table, sfeatures); + zprop_register_index(ZFS_PROP_DEVDISK, "com.apple.devdisk", 0, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "poolonly | on | off", + "COM.APPLE.DEVDISK", devdisk_table, sfeatures); + /* __APPLE__ */ + /* readonly number properties */ zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY, ZFS_TYPE_DATASET, "", "USED", B_FALSE, sfeatures); diff --git a/module/zcommon/zprop_common.c b/module/zcommon/zprop_common.c index eb635b38ceb5..a6d707df4b76 100644 --- a/module/zcommon/zprop_common.c +++ b/module/zcommon/zprop_common.c @@ -82,7 +82,8 @@ zfs_mod_supported_prop(const char *name, zfs_type_t type, * The equivalent _can_ be done on FreeBSD by way of the sysctl * tree, but this has not been done yet. */ -#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) || defined(__FreeBSD__) +#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD) || \ + defined(__FreeBSD__) || defined(__APPLE__) (void) name, (void) type, (void) sfeatures; return (B_TRUE); #else diff --git a/module/zfs/blake3_zfs.c b/module/zfs/blake3_zfs.c index 7783282b671a..50924534695b 100644 --- a/module/zfs/blake3_zfs.c +++ b/module/zfs/blake3_zfs.c @@ -49,7 +49,7 @@ abd_checksum_blake3_native(abd_t *abd, uint64_t size, const void *ctx_template, { ASSERT(ctx_template != NULL); -#if defined(_KERNEL) +#if defined(_KERNEL) && !(defined(__APPLE__) && defined(__aarch64__)) kpreempt_disable(); BLAKE3_CTX *ctx = blake3_per_cpu_ctx[CPU_SEQID]; #else @@ -60,7 +60,8 @@ abd_checksum_blake3_native(abd_t *abd, uint64_t size, const void *ctx_template, (void) abd_iterate_func(abd, 0, size, blake3_incremental, ctx); Blake3_Final(ctx, (uint8_t *)zcp); -#if defined(_KERNEL) +#if defined(_KERNEL) && !(defined(__APPLE__) && defined(__aarch64__)) + /* To keep conditionals the same */ kpreempt_enable(); #else memset(ctx, 0, sizeof (*ctx)); diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index b7453578a76f..cda019356caa 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -3826,7 +3826,9 @@ dbuf_rm_spill(dnode_t *dn, dmu_tx_t *tx) dbuf_free_range(dn, DMU_SPILL_BLKID, DMU_SPILL_BLKID, tx); } +#ifndef __APPLE__ #pragma weak dmu_buf_add_ref = dbuf_add_ref +#endif void dbuf_add_ref(dmu_buf_impl_t *db, const void *tag) { @@ -3834,7 +3836,19 @@ dbuf_add_ref(dmu_buf_impl_t *db, const void *tag) VERIFY3S(holds, >, 1); } +#ifdef __APPLE__ +/* No #pragma weaks here! */ +void +dmu_buf_add_ref(dmu_buf_t *db, const void *tag) +{ + dbuf_add_ref((dmu_buf_impl_t *)db, tag); +} +#endif + +#ifndef __APPLE__ #pragma weak dmu_buf_try_add_ref = dbuf_try_add_ref +#endif + boolean_t dbuf_try_add_ref(dmu_buf_t *db_fake, objset_t *os, uint64_t obj, uint64_t blkid, const void *tag) @@ -3858,6 +3872,15 @@ dbuf_try_add_ref(dmu_buf_t *db_fake, objset_t *os, uint64_t obj, uint64_t blkid, return (result); } +#ifdef __APPLE__ +boolean_t +dmu_buf_try_add_ref(dmu_buf_t *db, objset_t *os, uint64_t object, + uint64_t blkid, const void *tag) +{ + return (dbuf_try_add_ref(db, os, object, blkid, tag)); +} +#endif + /* * If you call dbuf_rele() you had better not be referencing the dnode handle * unless you have some other direct or indirect hold on the dnode. (An indirect diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 5e6e4e3d6c39..f835669178d5 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2703,6 +2703,22 @@ spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj, return (0); } +#if defined(__APPLE__) && defined(_KERNEL) + /* + * Unfortunate errata case, see module/os/macos/zfs/zio_crypt.c + * If portable is GOOD, but local_mac is BAD - recompute. + * We were hoping this would not be required after the work + * on the incompatibilities, but users complain they can not + * mount older crypted datasets. + */ + if (memcmp(portable_mac, osp->os_portable_mac, + ZIO_OBJSET_MAC_LEN) == 0 && + memcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) { + ret = zio_crypt_do_objset_hmacs_errata1(&dck->dck_key, buf, + datalen, byteswap, portable_mac, local_mac); + } +#endif + if (memcmp(portable_mac, osp->os_portable_mac, ZIO_OBJSET_MAC_LEN) != 0 || memcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) { diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index 34012db82dee..d40bf87b86c6 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -3488,8 +3488,13 @@ scan_io_queues_run(dsl_scan_t *scn) * scan_io_queues_run_one can occur during spa_sync runs * and that significantly impacts performance. */ +#if defined(__APPLE__) && defined(_KERNEL) + scn->scn_taskq = taskq_create("dsl_scan_iss", nthreads, + dsl_scan_iss_syspri, nthreads, nthreads, TASKQ_PREPOPULATE); +#else scn->scn_taskq = taskq_create("dsl_scan_iss", nthreads, minclsyspri, nthreads, nthreads, TASKQ_PREPOPULATE); +#endif } for (uint64_t i = 0; i < spa->spa_root_vdev->vdev_children; i++) { diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index 20dc934593f1..0fa8a4a4ba62 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -855,9 +855,14 @@ metaslab_group_create(metaslab_class_t *mc, vdev_t *vd, int allocators) metaslab_group_allocator_t *mga = &mg->mg_allocator[i]; zfs_refcount_create_tracked(&mga->mga_alloc_queue_depth); } - +#if defined(__APPLE__) && defined(_KERNEL) + mg->mg_taskq = taskq_create("metaslab_group_taskq", metaslab_load_pct, + maxclsyspri, 10, INT_MAX, TASKQ_THREADS_CPU_PCT | TASKQ_DYNAMIC + | TASKQ_REALLY_DYNAMIC); +#else mg->mg_taskq = taskq_create("metaslab_group_taskq", metaslab_load_pct, maxclsyspri, 10, INT_MAX, TASKQ_THREADS_CPU_PCT | TASKQ_DYNAMIC); +#endif return (mg); } diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 88ee4ea9f458..88d530556fc9 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -1128,6 +1128,27 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) pri++; #elif defined(__FreeBSD__) pri += 4; +#elif defined(__APPLE__) + pri -= 4; +#if defined(_KERNEL) + } else { + /* + * we want to be below maclsyspri for zio + * taskqs on macOS, to avoid starving out + * base=81 (maxclsyspri) kernel tasks when + * doing computation-intensive checksums etc. + */ + pri -= 1; + } + /* macOS cannot handle TASKQ_DYNAMIC zio taskqs */ + + if ((flags & (TASKQ_DC_BATCH|TASKQ_DUTY_CYCLE)) == 0) + flags |= TASKQ_TIMESHARE; + + if (flags & TASKQ_DYNAMIC) { + flags &= ~TASKQ_DYNAMIC; + /* fallthrough to closing brace after #endif */ +#endif #else #error "unknown OS" #endif @@ -6326,12 +6347,12 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT); + spa_import_os(spa); + mutex_exit(&spa_namespace_lock); zvol_create_minors_recursive(pool); - spa_import_os(spa); - return (0); } diff --git a/module/zfs/spa_errlog.c b/module/zfs/spa_errlog.c index 2e5c22c11490..ff39c0d07470 100644 --- a/module/zfs/spa_errlog.c +++ b/module/zfs/spa_errlog.c @@ -303,7 +303,7 @@ copyout_entry(const zbookmark_phys_t *zb, void *uaddr, uint64_t *count) return (SET_ERROR(ENOMEM)); *count -= 1; - if (copyout(zb, (char *)uaddr + (*count) * sizeof (zbookmark_phys_t), + if (xcopyout(zb, (char *)uaddr + (*count) * sizeof (zbookmark_phys_t), sizeof (zbookmark_phys_t)) != 0) return (SET_ERROR(EFAULT)); return (0); diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 3b355e0debcc..95316fed1ebb 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -639,7 +639,7 @@ spa_deadman(void *arg) zfs_dbgmsg("slow spa_sync: started %llu seconds ago, calls %llu", (gethrtime() - spa->spa_sync_starttime) / NANOSEC, (u_longlong_t)++spa->spa_deadman_calls); - if (zfs_deadman_enabled) + if (zfs_deadman_enabled && spa->spa_root_vdev != NULL) vdev_deadman(spa->spa_root_vdev, FTAG); spa->spa_deadman_tqid = taskq_dispatch_delay(system_delay_taskq, diff --git a/module/zfs/vdev_raidz_math.c b/module/zfs/vdev_raidz_math.c index e12b96170f55..5385e2510597 100644 --- a/module/zfs/vdev_raidz_math.c +++ b/module/zfs/vdev_raidz_math.c @@ -61,7 +61,7 @@ static const raidz_impl_ops_t *const raidz_all_maths[] = { #if defined(__x86_64) && defined(HAVE_AVX512BW) /* only x86_64 for now */ &vdev_raidz_avx512bw_impl, #endif -#if defined(__aarch64__) && !defined(__FreeBSD__) +#if defined(__aarch64__) && !defined(__FreeBSD__) && !defined(__APPLE__) &vdev_raidz_aarch64_neon_impl, &vdev_raidz_aarch64_neonx2_impl, #endif @@ -633,14 +633,17 @@ vdev_raidz_impl_set(const char *val) return (err); } -#if defined(_KERNEL) && defined(__linux__) +#if defined(_KERNEL) +#if defined(__linux__) static int zfs_vdev_raidz_impl_set(const char *val, zfs_kernel_param_t *kp) { return (vdev_raidz_impl_set(val)); } +#endif +#if defined(__linux__) || defined(__APPLE__) static int zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp) { @@ -667,6 +670,29 @@ zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp) return (cnt); } +#endif /* defined(Linux) || defined(APPLE) */ + +#if defined(__APPLE__) +/* get / set function */ +int +param_zfs_vdev_raidz_impl_set(ZFS_MODULE_PARAM_ARGS) +{ + char buf[1024]; /* Linux module string limit */ + int rc = 0; + + /* Always fill in value before calling sysctl_handle_*() */ + if (req->newptr == (user_addr_t)NULL) + (void) zfs_vdev_raidz_impl_get(buf, NULL); + + rc = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (rc || req->newptr == (user_addr_t)NULL) + return (rc); + + rc = vdev_raidz_impl_set(buf); + return (rc); +} +#endif /* defined(APPLE) */ + module_param_call(zfs_vdev_raidz_impl, zfs_vdev_raidz_impl_set, zfs_vdev_raidz_impl_get, NULL, 0644); MODULE_PARM_DESC(zfs_vdev_raidz_impl, "Select raidz implementation."); diff --git a/module/zfs/zfs_fuid.c b/module/zfs/zfs_fuid.c index add4241dcc99..301ab70a8339 100644 --- a/module/zfs/zfs_fuid.c +++ b/module/zfs/zfs_fuid.c @@ -409,7 +409,24 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, */ return (fuid); } +#elif defined(__APPLE__) +uid_t +zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, + cred_t *cr, zfs_fuid_type_t type) +{ + uint32_t index = FUID_INDEX(fuid); + const char *domain; + uid_t id; + if (index == 0) + return (fuid); + + domain = zfs_fuid_find_by_idx(zfsvfs, index); + ASSERT(domain != NULL); + + id = UID_NOBODY; + return (id); +} #else uid_t zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index f91a2f3bbca5..d881c5353ab0 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -7026,7 +7026,7 @@ zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func, vec->zvec_nvl_key_count = num_keys; } -static void +void zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy, boolean_t log_history, zfs_ioc_poolcheck_t pool_check) diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c index 50325907b0d1..3beff3ce3998 100644 --- a/module/zfs/zfs_log.c +++ b/module/zfs/zfs_log.c @@ -253,6 +253,28 @@ zfs_xattr_owner_unlinked(znode_t *zp) } if (tzp != zp) zrele(tzp); +#elif defined(__APPLE__) + znode_t *tzp = zp; + + /* + * if zp is XATTR node, keep walking up via z_xattr_parent + * until we get the owner + */ + while (tzp->z_pflags & ZFS_XATTR) { + ASSERT3U(tzp->z_xattr_parent, !=, 0); + if (zfs_zget(ZTOZSB(tzp), tzp->z_xattr_parent, + &dzp) != 0) { + unlinked = 1; + break; + } + + if (tzp != zp) + zrele(tzp); + tzp = dzp; + unlinked = tzp->z_unlinked; + } + if (tzp != zp) + zrele(tzp); #else zhold(zp); /* diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c index fb2443b756f8..4d41ff715511 100644 --- a/module/zfs/zfs_sa.c +++ b/module/zfs/zfs_sa.c @@ -67,6 +67,8 @@ const sa_attr_reg_t zfs_attr_table[ZPL_END+1] = { {"ZPL_DACL_ACES", 0, SA_ACL, 0}, {"ZPL_DXATTR", 0, SA_UINT8_ARRAY, 0}, {"ZPL_PROJID", sizeof (uint64_t), SA_UINT64_ARRAY, 0}, + {"ZPL_ADDTIME", sizeof (uint64_t) * 2, SA_UINT64_ARRAY, 0}, + {"ZPL_DOCUMENTID", sizeof (uint64_t), SA_UINT64_ARRAY, 0}, {NULL, 0, 0, 0} }; diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 8a3b08139b6b..90b1932852a9 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -58,6 +58,8 @@ #include +#ifndef __APPLE__ + static ulong_t zfs_fsync_sync_cnt = 4; int @@ -81,7 +83,7 @@ zfs_fsync(znode_t *zp, int syncflag, cred_t *cr) return (error); } - +#endif #if defined(SEEK_HOLE) && defined(SEEK_DATA) /* @@ -579,7 +581,7 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr) ASSERT(abuf != NULL); ASSERT(arc_buf_size(abuf) == blksz); if ((error = zfs_uiocopy(abuf->b_data, blksz, - UIO_WRITE, uio, &nbytes))) { + UIO_WRITE, uio, (size_t *)&nbytes))) { dmu_return_arcbuf(abuf); break; } @@ -845,8 +847,13 @@ zfs_get_data(void *arg, uint64_t gen, lr_write_t *lr, char *buf, /* * Nothing to do if the file has been removed */ +#ifndef __APPLE__ if (zfs_zget(zfsvfs, object, &zp) != 0) return (SET_ERROR(ENOENT)); +#else + if (zfs_zget_ext(zfsvfs, object, &zp, ZGET_FLAG_ASYNC) != 0) + return (SET_ERROR(ENOENT)); +#endif if (zp->z_unlinked) { /* * Release the vnode asynchronously as we currently have the diff --git a/module/zfs/zio.c b/module/zfs/zio.c index b5627109900c..44d4f83de6e8 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -1989,8 +1989,8 @@ zio_taskq_dispatch(zio_t *zio, zio_taskq_type_t q, boolean_t cutinline) * to dispatch the zio to another taskq at the same time. */ ASSERT(taskq_empty_ent(&zio->io_tqent)); - spa_taskq_dispatch_ent(spa, t, q, zio_execute, zio, flags, - &zio->io_tqent); + spa_taskq_dispatch_ent(spa, t, q, zio_execute, zio, + flags, &zio->io_tqent); } static boolean_t diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index bbef53e4e479..e658aaf7c41f 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -90,7 +90,7 @@ unsigned int zvol_inhibit_dev = 0; unsigned int zvol_volmode = ZFS_VOLMODE_GEOM; struct hlist_head *zvol_htable; -static list_t zvol_state_list; +list_t zvol_state_list; krwlock_t zvol_state_lock; typedef enum { diff --git a/module/zstd/include/limits.h b/module/zstd/include/limits.h index 3bf5b67765ae..fdd3e3dc724a 100644 --- a/module/zstd/include/limits.h +++ b/module/zstd/include/limits.h @@ -48,6 +48,7 @@ extern "C" { #elif defined(__linux__) #include #include +#elif defined(__APPLE__) #else #error "Unsupported platform" #endif diff --git a/module/zstd/include/stddef.h b/module/zstd/include/stddef.h index 3f46fb8b033e..5805ab76248d 100644 --- a/module/zstd/include/stddef.h +++ b/module/zstd/include/stddef.h @@ -47,6 +47,7 @@ extern "C" { #include #elif defined(__linux__) #include +#elif defined(__APPLE__) #else #error "Unsupported platform" #endif diff --git a/module/zstd/include/stdint.h b/module/zstd/include/stdint.h index 2d98a556c23e..6ce1f435603c 100644 --- a/module/zstd/include/stdint.h +++ b/module/zstd/include/stdint.h @@ -47,6 +47,7 @@ extern "C" { #include #elif defined(__linux__) #include +#elif defined(__APPLE__) #else #error "Unsupported platform" #endif diff --git a/module/zstd/include/string.h b/module/zstd/include/string.h index 7474e7f1af0f..cd7e13784e01 100644 --- a/module/zstd/include/string.h +++ b/module/zstd/include/string.h @@ -48,6 +48,7 @@ extern "C" { #include /* memcpy, memset */ #elif defined(__linux__) #include /* memcpy, memset */ +#elif defined(__APPLE__) #else #error "Unsupported platform" #endif diff --git a/module/zstd/lib/common/zstd_internal.h b/module/zstd/lib/common/zstd_internal.h index 4a86d186a967..e7d37f5b7939 100644 --- a/module/zstd/lib/common/zstd_internal.h +++ b/module/zstd/lib/common/zstd_internal.h @@ -19,7 +19,7 @@ /*-************************************* * Dependencies ***************************************/ -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) && !defined(__APPLE__) #include #endif #include "compiler.h" @@ -227,7 +227,7 @@ static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; * Shared functions to include for inlining *********************************************/ static void ZSTD_copy8(void* dst, const void* src) { -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) && !defined(__APPLE__) vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src)); #else memcpy(dst, src, 8); @@ -236,7 +236,7 @@ static void ZSTD_copy8(void* dst, const void* src) { #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } static void ZSTD_copy16(void* dst, const void* src) { -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) && !defined(__APPLE__) vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src)); #else memcpy(dst, src, 16); @@ -260,7 +260,7 @@ typedef enum { * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart. * The src buffer must be before the dst buffer. */ -MEM_STATIC FORCE_INLINE_ATTR +MEM_STATIC FORCE_INLINE_ATTR void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype) { ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src; diff --git a/scripts/load_macos.sh b/scripts/load_macos.sh new file mode 100644 index 000000000000..36d2c9bc5338 --- /dev/null +++ b/scripts/load_macos.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Expected to be run from the root of the source tree, as root; +# ./scripts/load_macos.sh +# +# Copies compiled zfs.kext to /tmp/ and prepares the requirements +# for load. +# + +rsync -ar module/os/macos/zfs.kext/ /tmp/zfs.kext/ + +chown -R root:wheel /tmp/zfs.kext + +kextload -v /tmp/zfs.kext || kextutil /tmp/zfs.kext + +# log stream --source --predicate 'sender == "zfs"' --style compact diff --git a/scripts/pkg_macos.sh b/scripts/pkg_macos.sh new file mode 100644 index 000000000000..6b5e761678fa --- /dev/null +++ b/scripts/pkg_macos.sh @@ -0,0 +1,460 @@ +#!/usr/bin/env bash + +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# + +# Copyright (c) 2020 by ilovezfs +# Copyright (c) 2020 by Jorgen Lundman + +# +# A script to produce an installable .pkg for macOS. +# +# Environment variables: +# +# $PKG_CODESIGN_KEY: Set to name of certificate for codesigning, +# as named in Keychain. For example; +# "Developer ID Application: Joergen Lundman (735AM5QEU3)" +# +# $PKG_NOTARIZE_KEY: Set to the notarize key you can create on +# Apple developer pages. For example; +# "awvz-fqoi-cxag-tymn" +# +# $PKG_INSTALL_KEY: Set to the name of certificate for installer +# signing, as named in Keychain, For example; +# "Developer ID Installer: Joergen Lundman (735AM5QEU3)" +# + +BASE_DIR=$(dirname "$0") +SCRIPT_COMMON=common.sh +if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then + . "${BASE_DIR}/${SCRIPT_COMMON}" +else + echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 +fi + +WORKNAME="macos-root" +WORKDIR="/private/var/tmp/${WORKNAME}" + +# If there are two dots "10.15.4", eat it +OS=$(sw_vers | awk '{if ($1 == "ProductVersion:") print $2;}') +OS=$(echo "$OS" | awk -F . '{if ($1 == 10) print $1"."$2; else print $1}') +RC=$(grep Release: META | awk '$2 ~ /rc/ { print $2}') + +function usage +{ + echo "$0: Create installable pkg for macOS" + echo "" + echo " Options:" + echo " -l skip make install step, using a folder of a previous run" + echo " -L copy and fix external libraries" + exit +} + +while getopts "hlL" opt; do + case $opt in + l ) skip_install=1 ;; + L ) fix_libraries=1 ;; + h ) usage + exit 2 + ;; + * ) echo "Invalid argument: -$OPTARG"; + usage + exit 1 + esac +done + +case ${OS} in + 10.8|10.9|10.10|10.11|10.12|10.13) + unset PKG_NOTARIZE_KEY + echo "No notarize for OS $OS" + ;; +esac + +# pass remaining arguments on +shift $((OPTIND - 1)) + + +echo "" +echo "Creating pkg for macOS installation... " +echo "" + +if [ -z "$PKG_CODESIGN_KEY" ]; then + echo "\$PKG_CODESIGN_KEY not set to certificate name, skipping codesign." +fi + +if [ -z "$PKG_NOTARIZE_KEY" ]; then + echo "\$PKG_NOTARIZE_KEY not set to pass-key, skipping notarize." +fi + +if [ -z "$PKG_INSTALL_KEY" ]; then + echo "\$PKG_INSTALL_KEY not set to certificate name, skipping pkg install signing." +fi + +version=$(awk < META '{if ($1 == "Version:") print $2;}') +prefix="/usr/local" +if [ -f "${BASE_DIR}/../config.status" ]; then + prefix=$(grep 'S\["prefix"\]' "${BASE_DIR}/../config.status" | tr '=' ' ' | awk '{print $2;}' | tr -d '"') +fi + +echo "Version is $version" +echo "Prefix set to $prefix" +echo "RC, if set: $RC" +echo "" + +sleep 3 + +if [ -z $skip_install ]; then + rm -rf ${WORKDIR} || true + + mkdir -p ${WORKDIR} || fail "Unable to create $WORKDIR" + + echo "Running \"make install DESTDIR=$WORKDIR\" ... " + make install DESTDIR="${WORKDIR}" || fail "Make install failed." +fi + +echo "" +echo "make install completed." +echo "" + +# Make an attempt to figure out where "zpool" is installed to, +# repo default is /usr/local/sbin/ but macOS prefers /usr/local/bin +pushd $WORKDIR || fail "failed to create workdir" +file=$(find usr -type f -name zpool) +bindir=$(dirname "$file") +popd || fail "failed to popd" + +codesign_dirs=" +${WORKDIR}/Library/Extensions/zfs.kext/ +" +codesign_files=" +${WORKDIR}/${bindir}/zdb +${WORKDIR}/${bindir}/zed +${WORKDIR}/${bindir}/zfs +${WORKDIR}/${bindir}/zhack +${WORKDIR}/${bindir}/zinject +${WORKDIR}/${bindir}/zpool +${WORKDIR}/${bindir}/zstream +${WORKDIR}/${bindir}/ztest +${WORKDIR}/${bindir}/zfs_ids_to_path +${WORKDIR}/${bindir}/InvariantDisks +${WORKDIR}/${bindir}/zfs_util +${WORKDIR}/${bindir}/zconfigd +${WORKDIR}/${bindir}/zsysctl +${WORKDIR}/${bindir}/mount_zfs +${WORKDIR}/${prefix}/libexec/zfs/zpool_influxdb +${WORKDIR}/${prefix}/lib/libnvpair.a +${WORKDIR}/${prefix}/lib/libuutil.a +${WORKDIR}/${prefix}/lib/libzfs.a +${WORKDIR}/${prefix}/lib/libzpool.a +${WORKDIR}/${prefix}/lib/libzfs_core.a +${WORKDIR}/${prefix}/lib/librt.so.1 +${WORKDIR}/${prefix}/lib/libnvpair.?.dylib +${WORKDIR}/${prefix}/lib/libuutil.?.dylib +${WORKDIR}/${prefix}/lib/libzfs.?.dylib +${WORKDIR}/${prefix}/lib/libzpool.?.dylib +${WORKDIR}/${prefix}/lib/libzfs_core.?.dylib +${WORKDIR}/${prefix}/lib/libzfsbootenv.?.dylib +${WORKDIR}/Library/Filesystems/zfs.fs/Contents/Resources/zfs_util +${WORKDIR}/Library/Filesystems/zfs.fs/Contents/Resources/mount_zfs +" + +codesign_all="$codesign_files $codesign_dirs" + +function fail +{ + echo "$@" + exit 1 +} + +function do_unlock +{ + cert=$1 + + echo "Looking for certificate ${cert} ..." + + keychain=$(security find-certificate -c "${cert}" | awk '{if ($1 == "keychain:") print $2;}'|tr -d '"') + + echo "Unlocking keychain $keychain ..." + security unlock-keychain "${keychain}" || fail "Unable to unlock keychain" + + retval=${keychain} +} + +function do_codesign +{ + failures=0 + + echo "" + + do_unlock "${PKG_CODESIGN_KEY}" + + echo "OS $OS" + if [ x"$OS" == x"10.12" ] || + [ x"$OS" == x"10.11" ] || + [ x"$OS" == x"10.10" ] || + [ x"$OS" == x"10.9" ]; then + extra="" + else + extra="--options runtime" + fi + + for file in ${codesign_all} + do + echo "$file" + codesign --timestamp ${extra} -fvs "${PKG_CODESIGN_KEY}" "${file}" || failures=$((failures+1)) + done + + if [ "$failures" -ne 0 ]; then + echo "codesign phase had $failures issues ..." + exit 1 + fi + + # Look into where mount_zfs umount_zfs fsck_zfs went .. + # also: InvariantDisks +} + +# Delete everything in a directory, keeping a list +# of files. +# argument 1: directory path "/tmp/dir" +# argument 2: keep list "(item1|item2|tem3)" +function delete_and_keep +{ + # Keep only commands that apply to macOS + directory="$1" + keep="$2" + + pushd "${directory}" || fail "Unable to cd to ${directory}" + + shopt -s extglob + + for file in * + do + # shellcheck disable=SC2254 + case "${file}" in + !${keep}) + echo "Deleting non macOS file \"$file\"" + rm -f "${file}" + ;; + *) + # echo "Not deleting $file" + esac + done + shopt -u extglob + popd || fail "failed to popd" +} + +function do_prune +{ + + delete_and_keep "${WORKDIR}/${bindir}/" "(zfs|zpool|zdb|zed|zhack|zinject|zstream|zstreamdump|ztest|InvariantDisks|zfs_util|zconfigd|arc_summary|arcstat|dbufstat|fsck.zfs|zilstat|zfs_ids_to_path|zpool_influxdb|zsysctl|mount_zfs)" + + pushd "${WORKDIR}" || fail "Unable to cd to ${WORKDIR}" + + # Using relative paths here for safety + rm -rf \ +"./${prefix}/share/zfs-macos/runfiles" \ +"./${prefix}/share/zfs-macos/test-runner" \ +"./${prefix}/share/zfs-macos/zfs-tests" \ +"./${prefix}/src" + + popd || fail "failed to popd" +} + +# Find any libraries we link with outside of zfs (and system). +# For example, /usr/local/opt/openssl/lib/libssl.1.1.0.dylib +# and copy them into /usr/local/zfs/lib - then update the paths to +# those libraries in all cmds and libraries. +# To do, handle "/usr/local/zfs/" from ./configure arguments (--prefix) +function copy_fix_libraries +{ + echo "Fixing external libraries ... " + fixlib=$(otool -L ${codesign_files} | egrep '/usr/local/opt/|/opt/local/lib/' |awk '{print $1;}' | grep '\.dylib$' | sort | uniq) + + # Add the libs into codesign list - both to be codesigned, and updated + # between themselves (libssl depends on libcrypt) + # copy over, build array of relative paths to add. + fixlib_relative="" + for lib in $fixlib + do + dir=$(dirname "$lib") + name=$(basename "$lib" .dylib) + echo " working on ${name}.dylib ..." + rsync -ar --include "${name}*" --exclude="*" "${dir}/" "${WORKDIR}/${prefix}/lib/" + fixlib_relative="${fixlib_relative} ${WORKDIR}/${prefix}/lib/${name}.dylib" + done + + echo "Adding in new libraries: " + echo "${fixlib_relative}" + + # Add new libraries + codesign_files="${codesign_files} ${fixlib_relative}" + codesign_all="${codesign_all} ${fixlib_relative}" + + # Fix up paths between binaries and libraries + for lib in $fixlib + do + dir=$(dirname "$lib") + name=$(basename "$lib" .dylib) + + # We could just change $lib into $prefix, which will work for + # zfs libraries. But libssl having libcrypto might have a different + # path, so lookup the source path each time. + for file in $codesign_files + do + chmod u+w "${file}" + src=$(otool -L "$file" | awk '{print $1;}' | grep "${name}.dylib") + install_name_tool -change "${src}" "${prefix}/lib/${name}.dylib" "${file}" + done + done +} + +# Upload .pkg file +# Staple .pkg file +function do_notarize +{ + echo "Uploading PKG to Apple ..." + + TFILE="out-altool.xml" + RFILE="req-altool.xml" + xcrun altool --notarize-app -f my_package_new.pkg --primary-bundle-id org.openzfsonosx.zfs -u lundman@lundman.net -p "$PKG_NOTARIZE_KEY" --output-format xml > ${TFILE} + + GUID=$(/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" ${TFILE}) + echo "Uploaded. GUID ${GUID}" + echo "Waiting for Apple to notarize..." + while true + do + sleep 10 + echo "Querying Apple." + + xcrun altool --notarization-info "${GUID}" -u lundman@lundman.net -p "$PKG_NOTARIZE_KEY" --output-format xml > ${RFILE} + status=$(/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" ${RFILE}) + if [ "$status" != "in progress" ]; then + echo "Status: $status ." + break + fi + echo "Status: $status - sleeping ..." + sleep 30 + done + + echo "Stapling PKG ..." + xcrun stapler staple my_package_new.pkg + ret=$? + xcrun stapler validate -v my_package_new.pkg + + if [ $ret != 0 ]; then + echo "Failed to notarize: $ret" + grep "https://" ${RFILE} + exit 1 + fi + +} + +echo "Pruning install area ..." +do_prune + +if [ -n "$fix_libraries" ]; then + copy_fix_libraries + copy_fix_libraries +fi + +if [ -n "$PKG_CODESIGN_KEY" ]; then + do_codesign +fi + +sleep 1 + +echo "Creating pkg ... " + +sign=() + +if [ -n "$PKG_INSTALL_KEY" ]; then + do_unlock "${PKG_INSTALL_KEY}" + #sign=(--sign "$PKG_INSTALL_KEY" --keychain "$retval" --keychain ~/Library/Keychains/login.keychain-db) + echo sign=--sign "$PKG_INSTALL_KEY" --keychain "$retval" + sign=(--sign "$PKG_INSTALL_KEY" --keychain "$retval") +fi + +rm -f my_package.pkg +pkgbuild --root "${WORKDIR}" --identifier org.openzfsonosx.zfs --version "${version}" --scripts "${BASE_DIR}/../contrib/macOS/pkg-scripts/" "${sign[@]}" my_package.pkg + +ret=$? + +echo "pkgbuild result $ret" + +if [ $ret != 0 ]; then + fail "pkgbuild failed" +fi + +friendly=$(awk '/SOFTWARE LICENSE AGREEMENT FOR macOS/' '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' | awk -F 'macOS ' '{print $NF}' | tr -d '\\') +if [ -z "$friendly" ]; then + friendly=$(awk '/SOFTWARE LICENSE AGREEMENT FOR OS X/' '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' | awk -F 'OS X ' '{print $NF}' | awk '{print substr($0, 0, length($0)-1)}') +fi + +friendly=$(echo "$friendly" | tr ' ' '.') + +# Now fiddle with pkg to make it nicer +productbuild --synthesize --package ./my_package.pkg distribution.xml + +sed < distribution.xml > distribution_new.xml -e \ +"s## Open ZFS on OsX ${version} - ${friendly}-${OS}\\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ +\\ +\\ +\\ +\\ +#g" + +sed -i "" \ + -e "/SCRIPT_REPLACE/{r ${BASE_DIR}/../contrib/macOS/resources/javascript.js" \ + -e 'd' -e '}' \ + distribution_new.xml + +rm -f my_package_new.pkg +productbuild --distribution distribution_new.xml --resources "${BASE_DIR}/../contrib/macOS/resources/" --scripts "${BASE_DIR}/../contrib/macOS/product-scripts" "${sign[@]}" --package-path ./my_package.pkg my_package_new.pkg + +if [ -n "$PKG_NOTARIZE_KEY" ]; then + SECONDS=0 + do_notarize + echo "Notarize took $SECONDS seconds to complete" +fi + +arch=$(uname -m) +if [ x"$arch" == x"arm64" ]; then + name="OpenZFSonOsX-${version}${RC}-${friendly}-${OS}-${arch}.pkg" +else + name="OpenZFSonOsX-${version}${RC}-${friendly}-${OS}.pkg" +fi + +mv my_package_new.pkg "${name}" +ls -l "${name}" + +# Cleanup +rm -f my_package.pkg distribution.xml distribution_new.xml req-altool.xml out-altool.xml + +echo "All done." diff --git a/scripts/zfs-tests.sh b/scripts/zfs-tests.sh index 179e24d7a0ef..6d99c8e73d4d 100755 --- a/scripts/zfs-tests.sh +++ b/scripts/zfs-tests.sh @@ -57,6 +57,10 @@ if [ "$UNAME" = "FreeBSD" ] ; then TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"} LOSETUP=/sbin/mdconfig DMSETUP=/sbin/gpart +elif [ "$UNAME" = "Darwin" ] ; then + TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"} + LOSETUP=/usr/bin/hdiutil + DMSETUP=/sbin/something2 else ZFS_MMP="$STF_SUITE/callbacks/zfs_mmp.ksh" TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DBGMSG:$ZFS_DMESG:$ZFS_MMP"} @@ -91,6 +95,16 @@ cleanup_freebsd_loopback() { done } +cleanup_macos_loopback() { + for TEST_LOOPBACK in ${LOOPBACKS}; do + sudo "$ZPOOL" export -a + if [ -b "${TEST_LOOPBACK}" ]; then + sudo "${LOSETUP}" detach "${TEST_LOOPBACK}" || + echo "Failed to destroy: ${TEST_LOOPBACK}" + fi + done +} + cleanup_linux_loopback() { for TEST_LOOPBACK in ${LOOPBACKS}; do LOOP_DEV="${TEST_LOOPBACK##*/}" @@ -123,6 +137,8 @@ cleanup() { if [ "$LOOPBACK" = "yes" ]; then if [ "$UNAME" = "FreeBSD" ] ; then cleanup_freebsd_loopback + elif [ "$UNAME" = "Darwin" ] ; then + cleanup_macos_loopback else cleanup_linux_loopback fi @@ -147,6 +163,8 @@ cleanup_all() { TEST_POOLS=$(ASAN_OPTIONS=detect_leaks=false "$ZPOOL" list -Ho name | grep testpool) if [ "$UNAME" = "FreeBSD" ] ; then TEST_LOOPBACKS=$(sudo "${LOSETUP}" -l) + elif [ "$UNAME" = "Darwin" ] ; then + TEST_LOOPBACKS=$(sudo "${LOSETUP}" info|grep /dev/disk) else TEST_LOOPBACKS=$("${LOSETUP}" -a | awk -F: '/file-vdev/ {print $1}') fi @@ -171,6 +189,8 @@ cleanup_all() { for TEST_LOOPBACK in $TEST_LOOPBACKS; do if [ "$UNAME" = "FreeBSD" ] ; then sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}" + elif [ "$UNAME" = "Darwin" ] ; then + sudo "${LOSETUP}" detach "${TEST_LOOPBACK}" else sudo "${LOSETUP}" -d "${TEST_LOOPBACK}" fi @@ -282,6 +302,8 @@ constrain_path() { SYSTEM_FILES="$SYSTEM_FILES_COMMON" if [ "$UNAME" = "FreeBSD" ] ; then SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_FREEBSD" + elif [ "$UNAME" = "Darwin" ] ; then + SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_MACOS" else SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_LINUX" fi @@ -295,6 +317,20 @@ constrain_path() { ln -fs "$STF_PATH/gunzip" "$STF_PATH/uncompress" elif [ "$UNAME" = "FreeBSD" ] ; then ln -fs /usr/local/bin/ksh93 "$STF_PATH/ksh" + elif [ "$UNAME" = "Darwin" ] ; then + [ -f "/usr/local/bin/gdd" ] && ln -fs /usr/local/bin/gdd "$STF_PATH/dd" + [ -f "/usr/local/bin/gsed" ] && ln -fs /usr/local/bin/gsed "$STF_PATH/gsed" + ln -fs /bin/ksh "$STF_PATH/ksh" + ln -fs /sbin/fsck_hfs "$STF_PATH/fsck" + ln -fs /sbin/newfs_hfs "$STF_PATH/newfs_hfs" + ln -fs /sbin/mount_hfs "$STF_PATH/mount" + ln -fs /usr/local/bin/gtruncate "$STF_PATH/truncate" + ln -fs /usr/sbin/sysctl "$STF_PATH/sysctl" + ln -fs /usr/bin/dscl "$STF_PATH/dscl" + ln -fs /usr/bin/xxd "$STF_PATH/xxd" + ln -fs /usr/sbin/dseditgroup "$STF_PATH/dseditgroup" + ln -fs /usr/bin/xattr "$STF_PATH/xattr" + ln -fs /usr/sbin/createhomedir "$STF_PATH/createhomedir" fi } @@ -521,6 +557,17 @@ fi [ -e "$STF_SUITE/include/default.cfg" ] || fail \ "Missing $STF_SUITE/include/default.cfg file." +if [ "$UNAME" = "Darwin" ]; then + DYLD_LIBRARY_PATH=$STF_SUITE/cmd/librt/.libs:$DYLD_LIBRARY_PATH + export DYLD_LIBRARY_PATH + # Tell ZFS to not to use /Volumes + __ZFS_MAIN_MOUNTPOINT_DIR=/ + export __ZFS_MAIN_MOUNTPOINT_DIR + # Catalina and up has root as read/only. + # BigSur gets even harder. + sudo /sbin/mount -uw / + export SHELL=ksh +fi # # Verify the ZFS module stack is loaded. # @@ -579,8 +626,15 @@ if [ -z "${DISKS}" ]; then # for TEST_FILE in ${FILES}; do [ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}" - truncate -s "${FILESIZE}" "${TEST_FILE}" || + + if [ "$UNAME" = "Darwin" ] ; then + mkfile -n "${FILESIZE}" "${TEST_FILE}" || fail "Failed creating: ${TEST_FILE} ($?)" + else + truncate -s "${FILESIZE}" "${TEST_FILE}" || + fail "Failed creating: ${TEST_FILE} ($?)" + fi + done # @@ -597,6 +651,21 @@ if [ -z "${DISKS}" ]; then fi DISKS="$DISKS $MDDEVICE" LOOPBACKS="$LOOPBACKS $MDDEVICE" + elif [ "$UNAME" = "Darwin" ] ; then + MDDEVICE=$(sudo "${LOSETUP}" attach -imagekey diskimage-class=CRawDiskImage -nomount "${TEST_FILE}") + if [ -z "$MDDEVICE" ] ; then + fail "Failed: ${TEST_FILE} -> loopback" + fi + LOOPBACKS="${LOOPBACKS}${MDDEVICE} " + BASEMDDEVICE=$(basename "$MDDEVICE") + if [ -z "$DISKS" ]; then + DISKS="$BASEMDDEVICE" + else + DISKS="$DISKS $BASEMDDEVICE" + fi + # If we use attached disk, remove the file-vdev + # from list. + DISKS=${DISKS:-"$TEST_FILE"} else TEST_LOOPBACK=$(sudo "${LOSETUP}" --show -f "${TEST_FILE}") || fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}" @@ -621,6 +690,8 @@ if [ "$TAGS" != "perf" ]; then [ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" fi +echo "Finished with DISKS $DISKS" + # # Disable SELinux until the ZFS Test Suite has been updated accordingly. # @@ -667,6 +738,8 @@ export TESTFAIL_CALLBACKS mktemp_file() { if [ "$UNAME" = "FreeBSD" ]; then mktemp -u "${FILEDIR}/$1.XXXXXX" + elif [ "$UNAME" = "Darwin" ]; then + mktemp -u "${FILEDIR}/$1.XXXXXX" else mktemp -ut "$1.XXXXXX" -p "$FILEDIR" fi diff --git a/tests/runfiles/darwin.run b/tests/runfiles/darwin.run new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/runfiles/large.run b/tests/runfiles/large.run new file mode 100644 index 000000000000..65de03497fbb --- /dev/null +++ b/tests/runfiles/large.run @@ -0,0 +1,822 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +[DEFAULT] +pre = setup +quiet = False +pre_user = root +user = root +timeout = 600 +post_user = root +post = cleanup +failsafe_user = root +failsafe = callbacks/zfs_failsafe +outputdir = /var/tmp/test_results +tags = ['functional'] + +[tests/functional/alloc_class] +tests = ['alloc_class_001_pos', 'alloc_class_002_neg', 'alloc_class_003_pos', + 'alloc_class_004_pos', 'alloc_class_005_pos', 'alloc_class_006_pos', + 'alloc_class_007_pos', 'alloc_class_008_pos', 'alloc_class_009_pos', + 'alloc_class_010_pos', 'alloc_class_011_neg', 'alloc_class_012_pos', + 'alloc_class_013_pos'] +tags = ['functional', 'alloc_class'] + +[tests/functional/atime] +tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on'] +tags = ['functional', 'atime'] + +[tests/functional/bootfs] +tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos', + 'bootfs_004_neg', +#macOS 10mins timeout +#'bootfs_005_neg', + 'bootfs_006_pos', 'bootfs_007_pos', + 'bootfs_008_pos'] +tags = ['functional', 'bootfs'] + +[tests/functional/btree] +tests = ['btree_positive', 'btree_negative'] +tags = ['functional', 'btree'] +pre = +post = + +[tests/functional/cache] +tests = ['cache_001_pos', 'cache_002_pos', 'cache_003_pos', 'cache_004_neg', + 'cache_005_neg', 'cache_006_pos', 'cache_007_neg', 'cache_008_neg', + 'cache_009_pos', 'cache_010_pos', 'cache_011_pos', 'cache_012_pos'] +tags = ['functional', 'cache'] + +[tests/functional/cachefile] +tests = ['cachefile_001_pos', 'cachefile_002_pos', 'cachefile_003_pos', + 'cachefile_004_pos'] +tags = ['functional', 'cachefile'] + +[tests/functional/casenorm] +tests = ['case_all_values', 'norm_all_values', +# 'mixed_create_failure', + 'sensitive_none_lookup', 'sensitive_none_delete', + 'sensitive_formd_lookup', 'sensitive_formd_delete', + 'insensitive_none_lookup', 'insensitive_none_delete', + 'insensitive_formd_lookup', 'insensitive_formd_delete', + 'mixed_none_lookup', 'mixed_none_lookup_ci', 'mixed_none_delete', + 'mixed_formd_lookup', 'mixed_formd_lookup_ci', 'mixed_formd_delete'] +tags = ['functional', 'casenorm'] + +[tests/functional/channel_program/lua_core] +tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists', + 'tst.integer_illegal', 'tst.integer_overflow', 'tst.language_functions_neg', + 'tst.language_functions_pos', 'tst.large_prog', +# 'tst.libraries', + 'tst.memory_limit', 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua', + 'tst.recursive_neg', 'tst.recursive_pos', 'tst.return_large', + 'tst.return_nvlist_neg', 'tst.return_nvlist_pos', + 'tst.return_recursive_table', 'tst.timeout'] +tags = ['functional', 'channel_program', 'lua_core'] + +[tests/functional/channel_program/synctask_core] +tests = ['tst.destroy_fs', 'tst.destroy_snap', 'tst.get_count_and_limit', + 'tst.get_index_props', 'tst.get_mountpoint', 'tst.get_neg', + 'tst.get_number_props', 'tst.get_string_props', 'tst.get_type', + 'tst.get_userquota', 'tst.get_written', 'tst.inherit', 'tst.list_bookmarks', + 'tst.list_children', 'tst.list_clones', 'tst.list_holds', + 'tst.list_snapshots', 'tst.list_system_props', + 'tst.list_user_props', 'tst.parse_args_neg','tst.promote_conflict', + 'tst.promote_multiple', 'tst.promote_simple', 'tst.rollback_mult', + 'tst.rollback_one', 'tst.set_props', 'tst.snapshot_destroy', 'tst.snapshot_neg', + 'tst.snapshot_recursive', 'tst.snapshot_simple', + 'tst.bookmark.create', 'tst.bookmark.copy' +# macOS +# 'tst.terminate_by_signal' + ] +tags = ['functional', 'channel_program', 'synctask_core'] + +[tests/functional/checksum] +tests = ['run_sha2_test', 'run_skein_test', 'filetest_001_pos'] +tags = ['functional', 'checksum'] + +[tests/functional/clean_mirror] +tests = [ 'clean_mirror_001_pos', 'clean_mirror_002_pos', + 'clean_mirror_003_pos', 'clean_mirror_004_pos'] +tags = ['functional', 'clean_mirror'] + +[tests/functional/cli_root/zdb] +tests = ['zdb_002_pos', 'zdb_003_pos', 'zdb_004_pos', 'zdb_005_pos', + 'zdb_006_pos', 'zdb_args_neg', 'zdb_args_pos', 'zdb_checksum', 'zdb_decompress', + 'zdb_object_range_neg', 'zdb_object_range_pos', 'zdb_display_block', + 'zdb_objset_id'] +pre = +post = +tags = ['functional', 'cli_root', 'zdb'] + +[tests/functional/cli_root/zfs] +tests = ['zfs_001_neg', 'zfs_002_pos'] +tags = ['functional', 'cli_root', 'zfs'] + +[tests/functional/cli_root/zfs_bookmark] +tests = ['zfs_bookmark_cliargs'] +tags = ['functional', 'cli_root', 'zfs_bookmark'] + +[tests/functional/cli_root/zfs_change-key] +tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format', + 'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location', + 'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones'] +tags = ['functional', 'cli_root', 'zfs_change-key'] + +[tests/functional/cli_root/zfs_clone] +tests = ['zfs_clone_001_neg', 'zfs_clone_002_pos', 'zfs_clone_003_pos', + 'zfs_clone_004_pos', 'zfs_clone_005_pos', 'zfs_clone_006_pos', + 'zfs_clone_007_pos', 'zfs_clone_008_neg', 'zfs_clone_009_neg', + 'zfs_clone_010_pos', 'zfs_clone_encrypted', 'zfs_clone_deeply_nested'] +tags = ['functional', 'cli_root', 'zfs_clone'] + +[tests/functional/cli_root/zfs_copies] +tests = ['zfs_copies_001_pos', 'zfs_copies_002_pos', 'zfs_copies_003_pos', + 'zfs_copies_004_neg', 'zfs_copies_005_neg', 'zfs_copies_006_pos'] +tags = ['functional', 'cli_root', 'zfs_copies'] + +[tests/functional/cli_root/zfs_create] +tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos', + 'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos', + 'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg', + 'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos', + 'zfs_create_013_pos', +# 'zfs_create_014_pos', # ZOL #11051 + 'zfs_create_encrypted', + 'zfs_create_crypt_combos', 'zfs_create_dryrun', 'zfs_create_verbose'] +tags = ['functional', 'cli_root', 'zfs_create'] + +[tests/functional/cli_root/zfs_destroy] +tests = ['zfs_clone_livelist_condense_and_disable', + 'zfs_clone_livelist_condense_races', 'zfs_destroy_001_pos', + 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', + 'zfs_destroy_004_pos', 'zfs_destroy_005_neg', 'zfs_destroy_006_neg', + 'zfs_destroy_007_neg', 'zfs_destroy_008_pos', 'zfs_destroy_009_pos', + 'zfs_destroy_010_pos', 'zfs_destroy_011_pos', 'zfs_destroy_012_pos', + 'zfs_destroy_013_neg', 'zfs_destroy_014_pos', 'zfs_destroy_015_pos', + 'zfs_destroy_016_pos', 'zfs_destroy_clone_livelist', + 'zfs_destroy_dev_removal', 'zfs_destroy_dev_removal_condense'] +tags = ['functional', 'cli_root', 'zfs_destroy'] + +[tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + +[tests/functional/cli_root/zfs_get] +tests = ['zfs_get_001_pos', 'zfs_get_002_pos', 'zfs_get_003_pos', + 'zfs_get_004_pos', 'zfs_get_005_neg', 'zfs_get_006_neg', 'zfs_get_007_neg', + 'zfs_get_008_pos', 'zfs_get_009_pos', 'zfs_get_010_neg'] +tags = ['functional', 'cli_root', 'zfs_get'] + +[tests/functional/cli_root/zfs_ids_to_path] +tests = ['zfs_ids_to_path_001_pos'] +tags = ['functional', 'cli_root', 'zfs_ids_to_path'] + +[tests/functional/cli_root/zfs_inherit] +tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg', 'zfs_inherit_003_pos', + 'zfs_inherit_mountpoint'] +tags = ['functional', 'cli_root', 'zfs_inherit'] + +[tests/functional/cli_root/zfs_load-key] +tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file', + 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive'] +tags = ['functional', 'cli_root', 'zfs_load-key'] + +[tests/functional/cli_root/zfs_mount] +tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos', + 'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_007_pos', + 'zfs_mount_009_neg', 'zfs_mount_010_neg', 'zfs_mount_011_neg', + 'zfs_mount_012_pos', 'zfs_mount_all_001_pos', 'zfs_mount_encrypted', + 'zfs_mount_remount', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints', + 'zfs_mount_test_race'] +tags = ['functional', 'cli_root', 'zfs_mount'] + +[tests/functional/cli_root/zfs_program] +tests = ['zfs_program_json'] +tags = ['functional', 'cli_root', 'zfs_program'] + +[tests/functional/cli_root/zfs_promote] +tests = ['zfs_promote_001_pos', 'zfs_promote_002_pos', 'zfs_promote_003_pos', + 'zfs_promote_004_pos', 'zfs_promote_005_pos', 'zfs_promote_006_neg', + 'zfs_promote_007_neg', 'zfs_promote_008_pos', 'zfs_promote_encryptionroot'] +tags = ['functional', 'cli_root', 'zfs_promote'] + +[tests/functional/cli_root/zfs_property] +tests = ['zfs_written_property_001_pos'] +tags = ['functional', 'cli_root', 'zfs_property'] + +[tests/functional/cli_root/zfs_receive] +tests = ['zfs_receive_001_pos', 'zfs_receive_002_pos', 'zfs_receive_003_pos', + 'zfs_receive_004_neg', 'zfs_receive_005_neg', 'zfs_receive_006_pos', + 'zfs_receive_007_neg', 'zfs_receive_008_pos', 'zfs_receive_009_neg', + 'zfs_receive_010_pos', 'zfs_receive_011_pos', 'zfs_receive_012_pos', + 'zfs_receive_013_pos', 'zfs_receive_014_pos', 'zfs_receive_015_pos', + 'zfs_receive_016_pos', 'receive-o-x_props_override', + 'zfs_receive_from_encrypted', 'zfs_receive_to_encrypted', + 'zfs_receive_raw', 'zfs_receive_raw_incremental', 'zfs_receive_-e', + 'zfs_receive_raw_-d'] +tags = ['functional', 'cli_root', 'zfs_receive'] + +[tests/functional/cli_root/zfs_rename] +tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos', + 'zfs_rename_004_neg', 'zfs_rename_005_neg', 'zfs_rename_006_pos', + 'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_009_neg', + 'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg', + 'zfs_rename_013_pos', 'zfs_rename_014_neg', 'zfs_rename_encrypted_child', + 'zfs_rename_to_encrypted', 'zfs_rename_mountpoint'] +tags = ['functional', 'cli_root', 'zfs_rename'] + +[tests/functional/cli_root/zfs_reservation] +tests = ['zfs_reservation_001_pos', 'zfs_reservation_002_pos'] +tags = ['functional', 'cli_root', 'zfs_reservation'] + +[tests/functional/cli_root/zfs_rollback] +tests = ['zfs_rollback_001_pos', 'zfs_rollback_002_pos', + 'zfs_rollback_003_neg', 'zfs_rollback_004_neg'] +tags = ['functional', 'cli_root', 'zfs_rollback'] + +[tests/functional/cli_root/zfs_send] +tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos', + 'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos', + 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw', + 'zfs_send_sparse', 'zfs_send-b'] +tags = ['functional', 'cli_root', 'zfs_send'] + +[tests/functional/cli_root/zfs_set] +tests = ['cache_001_pos', 'cache_002_neg', 'canmount_001_pos', + 'canmount_002_pos', 'canmount_003_pos', 'canmount_004_pos', + 'checksum_001_pos', 'compression_001_pos', 'mountpoint_001_pos', + 'mountpoint_002_pos', 'reservation_001_neg', 'user_property_002_pos', + 'share_mount_001_neg', 'snapdir_001_pos', 'onoffs_001_pos', + 'user_property_001_pos', 'user_property_003_neg', 'readonly_001_pos', + 'user_property_004_pos', 'version_001_neg', 'zfs_set_001_neg', + 'zfs_set_002_neg', 'zfs_set_003_neg', 'property_alias_001_pos', + 'mountpoint_003_pos', 'ro_props_001_pos', 'zfs_set_keylocation'] +tags = ['functional', 'cli_root', 'zfs_set'] + +[tests/functional/cli_root/zfs_share] +tests = ['zfs_share_001_pos', 'zfs_share_002_pos', 'zfs_share_003_pos', + 'zfs_share_004_pos', 'zfs_share_005_pos', 'zfs_share_006_pos', + 'zfs_share_007_neg', 'zfs_share_008_neg', 'zfs_share_009_neg', + 'zfs_share_010_neg', 'zfs_share_011_pos'] +tags = ['functional', 'cli_root', 'zfs_share'] + +[tests/functional/cli_root/zfs_snapshot] +tests = ['zfs_snapshot_001_neg', 'zfs_snapshot_002_neg', + 'zfs_snapshot_003_neg', 'zfs_snapshot_004_neg', 'zfs_snapshot_005_neg', + 'zfs_snapshot_006_pos', 'zfs_snapshot_007_neg', 'zfs_snapshot_008_neg', + 'zfs_snapshot_009_pos'] +tags = ['functional', 'cli_root', 'zfs_snapshot'] + +[tests/functional/cli_root/zfs_unload-key] +tests = ['zfs_unload-key', 'zfs_unload-key_all', 'zfs_unload-key_recursive'] +tags = ['functional', 'cli_root', 'zfs_unload-key'] + +[tests/functional/cli_root/zfs_unmount] +tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos', + 'zfs_unmount_004_pos', 'zfs_unmount_005_pos', + # KILLED: testpool/c/c/c/c/c/c/c/c/c/c + # 'zfs_unmount_006_pos', + 'zfs_unmount_007_neg', 'zfs_unmount_008_neg', 'zfs_unmount_009_pos', + 'zfs_unmount_all_001_pos', 'zfs_unmount_nested', 'zfs_unmount_unload_keys'] +tags = ['functional', 'cli_root', 'zfs_unmount'] + +[tests/functional/cli_root/zfs_unshare] +tests = ['zfs_unshare_001_pos', 'zfs_unshare_002_pos', 'zfs_unshare_003_pos', + 'zfs_unshare_004_neg', 'zfs_unshare_005_neg', 'zfs_unshare_006_pos', + 'zfs_unshare_007_pos'] +tags = ['functional', 'cli_root', 'zfs_unshare'] + +# macOS - known to panic +[tests/functional/cli_root/zfs_upgrade] +tests = ['zfs_upgrade_001_pos', 'zfs_upgrade_002_pos', 'zfs_upgrade_003_pos', +# 'zfs_upgrade_004_pos', + 'zfs_upgrade_005_pos', 'zfs_upgrade_006_neg', + 'zfs_upgrade_007_neg'] +tags = ['functional', 'cli_root', 'zfs_upgrade'] + +[tests/functional/cli_root/zfs_wait] +tests = ['zfs_wait_deleteq'] +tags = ['functional', 'cli_root', 'zfs_wait'] + +[tests/functional/cli_root/zpool] +tests = ['zpool_001_neg', 'zpool_002_pos', 'zpool_003_pos', 'zpool_colors'] +tags = ['functional', 'cli_root', 'zpool'] + +[tests/functional/cli_root/zpool_attach] +tests = ['zpool_attach_001_neg', 'attach-o_ashift'] +tags = ['functional', 'cli_root', 'zpool_attach'] + +[tests/functional/cli_root/zpool_clear] +tests = ['zpool_clear_001_pos', 'zpool_clear_002_neg', 'zpool_clear_003_neg', + 'zpool_clear_readonly'] +tags = ['functional', 'cli_root', 'zpool_clear'] + +[tests/functional/cli_root/zpool_create] +tests = ['zpool_create_001_pos', 'zpool_create_002_pos', + 'zpool_create_003_pos', 'zpool_create_004_pos', 'zpool_create_005_pos', + 'zpool_create_006_pos', 'zpool_create_007_neg', 'zpool_create_008_pos', + 'zpool_create_009_neg', 'zpool_create_010_neg', 'zpool_create_011_neg', + 'zpool_create_012_neg', 'zpool_create_014_neg', 'zpool_create_015_neg', + 'zpool_create_017_neg', 'zpool_create_018_pos', 'zpool_create_019_pos', + 'zpool_create_020_pos', 'zpool_create_021_pos', 'zpool_create_022_pos', + 'zpool_create_023_neg', +# 'zpool_create_024_pos', + 'zpool_create_encrypted', 'zpool_create_crypt_combos', + 'zpool_create_features_001_pos', 'zpool_create_features_002_pos', + 'zpool_create_features_003_pos', 'zpool_create_features_004_neg', + 'zpool_create_features_005_pos', + 'create-o_ashift', 'zpool_create_tempname'] +tags = ['functional', 'cli_root', 'zpool_create'] + +[tests/functional/cli_root/zpool_destroy] +tests = ['zpool_destroy_001_pos', 'zpool_destroy_002_pos', + 'zpool_destroy_003_neg'] +pre = +post = +tags = ['functional', 'cli_root', 'zpool_destroy'] + +[tests/functional/cli_root/zpool_detach] +tests = ['zpool_detach_001_neg'] +tags = ['functional', 'cli_root', 'zpool_detach'] + +[tests/functional/cli_root/zpool_events] +tests = ['zpool_events_clear', 'zpool_events_cliargs', 'zpool_events_follow', + 'zpool_events_poolname', 'zpool_events_errors'] +tags = ['functional', 'cli_root', 'zpool_events'] + +[tests/functional/cli_root/zpool_export] +tests = ['zpool_export_001_pos', 'zpool_export_002_pos', + 'zpool_export_003_neg', 'zpool_export_004_pos'] +tags = ['functional', 'cli_root', 'zpool_export'] + +[tests/functional/cli_root/zpool_get] +tests = ['zpool_get_001_pos', 'zpool_get_002_pos', 'zpool_get_003_pos', + 'zpool_get_004_neg', 'zpool_get_005_pos'] +tags = ['functional', 'cli_root', 'zpool_get'] + +[tests/functional/cli_root/zpool_history] +tests = ['zpool_history_001_neg', 'zpool_history_002_pos'] +tags = ['functional', 'cli_root', 'zpool_history'] + +[tests/functional/cli_root/zpool_import] +tests = ['zpool_import_001_pos', 'zpool_import_002_pos', + 'zpool_import_003_pos', 'zpool_import_004_pos', 'zpool_import_005_pos', + 'zpool_import_006_pos', 'zpool_import_007_pos', 'zpool_import_008_pos', + 'zpool_import_009_neg', 'zpool_import_010_pos', 'zpool_import_011_neg', + 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_014_pos', + 'zpool_import_015_pos', + 'zpool_import_features_001_pos', 'zpool_import_features_002_neg', + 'zpool_import_features_003_pos', 'zpool_import_missing_001_pos', + 'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos', + 'zpool_import_rename_001_pos', 'zpool_import_all_001_pos', + 'zpool_import_encrypted', 'zpool_import_encrypted_load', + 'zpool_import_errata3', 'zpool_import_errata4', + 'import_cachefile_device_added', + 'import_cachefile_device_removed', + 'import_cachefile_device_replaced', + 'import_cachefile_mirror_attached', + 'import_cachefile_mirror_detached', + 'import_cachefile_shared_device', + 'import_devices_missing', + 'import_paths_changed', +# 'import_rewind_config_changed', + 'import_rewind_device_replaced'] +tags = ['functional', 'cli_root', 'zpool_import'] + +[tests/functional/cli_root/zpool_labelclear] +tests = ['zpool_labelclear_active', 'zpool_labelclear_exported', + 'zpool_labelclear_removed', 'zpool_labelclear_valid'] +pre = +post = +tags = ['functional', 'cli_root', 'zpool_labelclear'] + +[tests/functional/cli_root/zpool_initialize] +tests = ['zpool_initialize_attach_detach_add_remove', + 'zpool_initialize_import_export', + 'zpool_initialize_offline_export_import_online', + 'zpool_initialize_online_offline', + 'zpool_initialize_split', + 'zpool_initialize_start_and_cancel_neg', + 'zpool_initialize_start_and_cancel_pos', + 'zpool_initialize_suspend_resume', + 'zpool_initialize_unsupported_vdevs', + 'zpool_initialize_verify_checksums', + 'zpool_initialize_verify_initialized'] +pre = +tags = ['functional', 'cli_root', 'zpool_initialize'] + +[tests/functional/cli_root/zpool_offline] +tests = ['zpool_offline_001_pos', 'zpool_offline_002_neg', + 'zpool_offline_003_pos'] +tags = ['functional', 'cli_root', 'zpool_offline'] + +[tests/functional/cli_root/zpool_online] +tests = ['zpool_online_001_pos', 'zpool_online_002_neg'] +tags = ['functional', 'cli_root', 'zpool_online'] + +[tests/functional/cli_root/zpool_remove] +tests = ['zpool_remove_001_neg', 'zpool_remove_002_pos', + 'zpool_remove_003_pos'] +tags = ['functional', 'cli_root', 'zpool_remove'] + +[tests/functional/cli_root/zpool_replace] +tests = ['zpool_replace_001_neg', 'replace-o_ashift', 'replace_prop_ashift'] +tags = ['functional', 'cli_root', 'zpool_replace'] + +[tests/functional/cli_root/zpool_resilver] +tests = ['zpool_resilver_bad_args', 'zpool_resilver_restart'] +tags = ['functional', 'cli_root', 'zpool_resilver'] + +[tests/functional/cli_root/zpool_scrub] +tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos', + 'zpool_scrub_004_pos', 'zpool_scrub_005_pos', + 'zpool_scrub_encrypted_unloaded', 'zpool_scrub_print_repairing', + 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies'] +tags = ['functional', 'cli_root', 'zpool_scrub'] + +[tests/functional/cli_root/zpool_set] +tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg', + 'zpool_set_ashift', 'zpool_set_features'] +tags = ['functional', 'cli_root', 'zpool_set'] + +[tests/functional/cli_root/zpool_split] +tests = ['zpool_split_cliargs', 'zpool_split_devices', + 'zpool_split_encryption', 'zpool_split_props', 'zpool_split_vdevs', + 'zpool_split_resilver', 'zpool_split_indirect'] +tags = ['functional', 'cli_root', 'zpool_split'] + +[tests/functional/cli_root/zpool_status] +tests = ['zpool_status_001_pos', 'zpool_status_002_pos'] +tags = ['functional', 'cli_root', 'zpool_status'] + +[tests/functional/cli_root/zpool_sync] +tests = ['zpool_sync_001_pos', 'zpool_sync_002_neg'] +tags = ['functional', 'cli_root', 'zpool_sync'] + +[tests/functional/cli_root/zpool_trim] +tests = ['zpool_trim_attach_detach_add_remove', + 'zpool_trim_import_export', 'zpool_trim_multiple', 'zpool_trim_neg', + 'zpool_trim_offline_export_import_online', 'zpool_trim_online_offline', + 'zpool_trim_partial', 'zpool_trim_rate', 'zpool_trim_rate_neg', + 'zpool_trim_secure', 'zpool_trim_split', 'zpool_trim_start_and_cancel_neg', + 'zpool_trim_start_and_cancel_pos', 'zpool_trim_suspend_resume', + 'zpool_trim_unsupported_vdevs', 'zpool_trim_verify_checksums', + 'zpool_trim_verify_trimmed'] +tags = ['functional', 'zpool_trim'] + +[tests/functional/cli_root/zpool_upgrade] +tests = ['zpool_upgrade_001_pos', 'zpool_upgrade_002_pos', + 'zpool_upgrade_003_pos', 'zpool_upgrade_004_pos', + 'zpool_upgrade_005_neg', 'zpool_upgrade_006_neg', +# macOS +# 'zpool_upgrade_007_pos', + 'zpool_upgrade_008_pos', + 'zpool_upgrade_009_neg'] +tags = ['functional', 'cli_root', 'zpool_upgrade'] + +[tests/functional/cli_root/zpool_wait/scan] +tests = ['zpool_wait_replace_cancel', 'zpool_wait_resilver', 'zpool_wait_scrub_cancel', + 'zpool_wait_replace', 'zpool_wait_scrub_basic', 'zpool_wait_scrub_flag'] +tags = ['functional', 'cli_root', 'zpool_wait'] + +[tests/functional/cli_user/zfs_list] +tests = ['zfs_list_001_pos', 'zfs_list_002_pos', 'zfs_list_003_pos', + 'zfs_list_004_neg', 'zfs_list_007_pos', 'zfs_list_008_neg'] +user = +tags = ['functional', 'cli_user', 'zfs_list'] + +[tests/functional/cli_user/zpool_iostat] +tests = ['zpool_iostat_001_neg', 'zpool_iostat_002_pos', + 'zpool_iostat_003_neg', 'zpool_iostat_004_pos', + 'zpool_iostat_005_pos', 'zpool_iostat_-c_disable', + 'zpool_iostat_-c_homedir', 'zpool_iostat_-c_searchpath'] +user = +tags = ['functional', 'cli_user', 'zpool_iostat'] + +[tests/functional/cli_user/zpool_list] +tests = ['zpool_list_001_pos', 'zpool_list_002_neg'] +user = +tags = ['functional', 'cli_user', 'zpool_list'] + +[tests/functional/cli_user/zpool_status] +tests = ['zpool_status_003_pos', 'zpool_status_-c_disable', + 'zpool_status_-c_homedir', 'zpool_status_-c_searchpath'] +user = +tags = ['functional', 'cli_user', 'zpool_status'] + +[tests/functional/compression] +tests = ['compress_001_pos', 'compress_002_pos', 'compress_003_pos'] +tags = ['functional', 'compression'] + +[tests/functional/cp_files] +tests = ['cp_files_001_pos'] +tags = ['functional', 'cp_files'] + +[tests/functional/ctime] +tests = ['ctime_001_pos' ] +tags = ['functional', 'ctime'] + +[tests/functional/delegate] +tests = ['zfs_allow_001_pos', 'zfs_allow_002_pos', 'zfs_allow_003_pos', + 'zfs_allow_004_pos', 'zfs_allow_005_pos', 'zfs_allow_006_pos', + 'zfs_allow_007_pos', 'zfs_allow_008_pos', 'zfs_allow_009_neg', + 'zfs_allow_010_pos', 'zfs_allow_011_neg', 'zfs_allow_012_neg', + 'zfs_unallow_001_pos', 'zfs_unallow_002_pos', 'zfs_unallow_003_pos', + 'zfs_unallow_004_pos', 'zfs_unallow_005_pos', 'zfs_unallow_006_pos', + 'zfs_unallow_007_neg', 'zfs_unallow_008_neg'] +tags = ['functional', 'delegate'] + +[tests/functional/exec] +tests = ['exec_001_pos', 'exec_002_neg'] +tags = ['functional', 'exec'] + +[tests/functional/features/async_destroy] +tests = ['async_destroy_001_pos'] +tags = ['functional', 'features', 'async_destroy'] + +[tests/functional/features/large_dnode] +tests = ['large_dnode_001_pos', 'large_dnode_003_pos', 'large_dnode_004_neg', + 'large_dnode_005_pos', 'large_dnode_007_neg', 'large_dnode_009_pos'] +tags = ['functional', 'features', 'large_dnode'] + +[tests/functional/grow] +pre = +post = +tests = ['grow_pool_001_pos', 'grow_replicas_001_pos'] +tags = ['functional', 'grow'] + +[tests/functional/history] +tests = ['history_001_pos', 'history_002_pos', 'history_003_pos', + 'history_004_pos', 'history_005_neg', 'history_006_neg', + 'history_007_pos', 'history_008_pos', 'history_009_pos', + 'history_010_pos'] +tags = ['functional', 'history'] + +[tests/functional/hkdf] +tests = ['run_hkdf_test'] +tags = ['functional', 'hkdf'] + +[tests/functional/inheritance] +tests = ['inherit_001_pos'] +pre = +tags = ['functional', 'inheritance'] + +[tests/functional/io] +tests = ['sync', 'psync', 'posixaio', 'mmap'] +tags = ['functional', 'io'] + +[tests/functional/inuse] +tests = ['inuse_004_pos', 'inuse_005_pos', 'inuse_008_pos', 'inuse_009_pos'] +post = +tags = ['functional', 'inuse'] + +[tests/functional/large_files] +tests = ['large_files_001_pos', 'large_files_002_pos'] +tags = ['functional', 'large_files'] + +[tests/functional/largest_pool] +tests = ['largest_pool_001_pos'] +pre = +post = +tags = ['functional', 'largest_pool'] + +[tests/functional/limits] +tests = ['filesystem_count', 'filesystem_limit', 'snapshot_count', + 'snapshot_limit'] +tags = ['functional', 'limits'] + +[tests/functional/link_count] +tests = ['link_count_001', 'link_count_root_inode'] +tags = ['functional', 'link_count'] + +[tests/functional/migration] +tests = ['migration_001_pos', 'migration_002_pos', 'migration_003_pos', + 'migration_004_pos', 'migration_005_pos', 'migration_006_pos', + 'migration_007_pos', 'migration_008_pos', 'migration_009_pos', + 'migration_010_pos', 'migration_011_pos', 'migration_012_pos'] +tags = ['functional', 'migration'] + +[tests/functional/mmap] +tests = ['mmap_write_001_pos', 'mmap_read_001_pos'] +tags = ['functional', 'mmap'] + +[tests/functional/mount] +tests = ['umount_001', 'umountall_001'] +tags = ['functional', 'mount'] + +[tests/functional/mv_files] +tests = ['mv_files_001_pos', 'mv_files_002_pos', 'random_creation'] +tags = ['functional', 'mv_files'] + +[tests/functional/nestedfs] +tests = ['nestedfs_001_pos'] +tags = ['functional', 'nestedfs'] + +[tests/functional/no_space] +tests = ['enospc_001_pos', 'enospc_002_pos', 'enospc_003_pos', + 'enospc_df'] +tags = ['functional', 'no_space'] + +[tests/functional/nopwrite] +tests = ['nopwrite_copies', 'nopwrite_mtime', 'nopwrite_negative', + 'nopwrite_promoted_clone', 'nopwrite_recsize', 'nopwrite_sync', + 'nopwrite_varying_compression', 'nopwrite_volume'] +tags = ['functional', 'nopwrite'] + +[tests/functional/online_offline] +tests = ['online_offline_001_pos', 'online_offline_002_neg', + 'online_offline_003_neg'] +tags = ['functional', 'online_offline'] + +[tests/functional/persist_l2arc] +tests = ['persist_l2arc_001_pos', 'persist_l2arc_002_pos', + 'persist_l2arc_003_neg', 'persist_l2arc_004_pos', 'persist_l2arc_005_pos', + 'persist_l2arc_006_pos', 'persist_l2arc_007_pos', 'persist_l2arc_008_pos'] +tags = ['functional', 'persist_l2arc'] + +[tests/functional/pool_names] +tests = ['pool_names_001_pos', # (run as root) [08:37] [PASS] + 'pool_names_002_neg'] +pre = +post = +tags = ['functional', 'pool_names'] + +[tests/functional/poolversion] +tests = ['poolversion_001_pos', 'poolversion_002_pos'] +tags = ['functional', 'poolversion'] + +[tests/functional/pyzfs] +tests = ['pyzfs_unittest'] +pre = +post = +tags = ['functional', 'pyzfs'] + +[tests/functional/quota] +tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', + 'quota_004_pos', 'quota_005_pos', 'quota_006_neg'] +tags = ['functional', 'quota'] + +[tests/functional/raidz] +tests = ['raidz_001_neg', 'raidz_002_pos'] +tags = ['functional', 'raidz'] + +[tests/functional/redundancy] +tests = ['redundancy_001_pos', 'redundancy_002_pos', 'redundancy_003_pos', + 'redundancy_004_neg'] +tags = ['functional', 'redundancy'] + +[tests/functional/refquota] +tests = ['refquota_001_pos', 'refquota_002_pos', 'refquota_003_pos', + 'refquota_004_pos', 'refquota_005_pos', 'refquota_006_neg', + 'refquota_007_neg', 'refquota_008_neg'] +tags = ['functional', 'refquota'] + +[tests/functional/refreserv] +tests = ['refreserv_001_pos', 'refreserv_002_pos', 'refreserv_003_pos', + 'refreserv_004_pos', 'refreserv_005_pos', 'refreserv_multi_raidz', + 'refreserv_raidz'] +tags = ['functional', 'refreserv'] + +[tests/functional/rename_dirs] +tests = ['rename_dirs_001_pos'] +tags = ['functional', 'rename_dirs'] + +[tests/functional/replacement] +tests = ['replacement_001_pos', 'replacement_002_pos', 'replacement_003_pos'] +tags = ['functional', 'replacement'] + +[tests/functional/resilver] +tests = ['resilver_restart_001', 'resilver_restart_002'] +tags = ['functional', 'resilver'] + +[tests/functional/rootpool] +tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos'] +tags = ['functional', 'rootpool'] + +[tests/functional/rsend] +tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos', + 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'rsend_005_pos', + 'rsend_006_pos', 'rsend_007_pos', 'rsend_008_pos', 'rsend_009_pos', + 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos', 'rsend_013_pos', + 'rsend_014_pos', 'rsend_016_neg', 'rsend_019_pos', 'rsend_020_pos', + 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos', + 'send-c_verify_ratio', 'send-c_verify_contents', 'send-c_props', + 'send-c_incremental', 'send-c_volume', 'send-c_zstreamdump', + 'send-c_lz4_disabled', 'send-c_recv_lz4_disabled', + 'send-c_mixed_compression', 'send-c_stream_size_estimate', + 'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize', + 'send-c_recv_dedup', 'send-L_toggle', 'send_encrypted_hierarchy', + 'send_encrypted_props', 'send_encrypted_truncated_files', + 'send_freeobjects', 'send_realloc_files', + 'send_realloc_encrypted_files', 'send_spill_block', 'send_holds', + 'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol', + 'send_partial_dataset'] +tags = ['functional', 'rsend'] + +[tests/functional/scrub_mirror] +tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', + 'scrub_mirror_003_pos', 'scrub_mirror_004_pos'] +tags = ['functional', 'scrub_mirror'] + +[tests/functional/snapshot] +tests = ['clone_001_pos', 'rollback_001_pos', 'rollback_002_pos', + 'rollback_003_pos', 'snapshot_001_pos', 'snapshot_002_pos', + 'snapshot_003_pos', 'snapshot_004_pos', 'snapshot_005_pos', + 'snapshot_006_pos', 'snapshot_007_pos', 'snapshot_008_pos', + 'snapshot_009_pos', 'snapshot_010_pos', 'snapshot_011_pos', + 'snapshot_012_pos', 'snapshot_013_pos', 'snapshot_014_pos', + 'snapshot_017_pos'] +tags = ['functional', 'snapshot'] + +[tests/functional/snapused] +tests = ['snapused_001_pos', 'snapused_002_pos', 'snapused_003_pos', + 'snapused_004_pos', 'snapused_005_pos'] +tags = ['functional', 'snapused'] + +[tests/functional/sparse] +tests = ['sparse_001_pos'] +tags = ['functional', 'sparse'] + +[tests/functional/suid] +tests = ['suid_write_to_suid', 'suid_write_to_sgid', 'suid_write_to_suid_sgid', + 'suid_write_to_none'] +tags = ['functional', 'suid'] + +[tests/functional/threadsappend] +tests = ['threadsappend_001_pos'] +tags = ['functional', 'threadsappend'] + +[tests/functional/trim] +tests = ['autotrim_integrity', 'autotrim_config', 'autotrim_trim_integrity', + 'trim_integrity', 'trim_config', 'trim_l2arc'] +tags = ['functional', 'trim'] + +[tests/functional/truncate] +tests = ['truncate_001_pos', 'truncate_002_pos', 'truncate_timestamps'] +tags = ['functional', 'truncate'] + +[tests/functional/upgrade] +tests = ['upgrade_userobj_001_pos', 'upgrade_readonly_pool'] +tags = ['functional', 'upgrade'] + +[tests/functional/userquota] +tests = [ + 'userquota_001_pos', 'userquota_002_pos', 'userquota_003_pos', + 'userquota_004_pos', 'userquota_005_neg', 'userquota_006_pos', + 'userquota_007_pos', 'userquota_008_pos', 'userquota_009_pos', + 'userquota_010_pos', 'userquota_011_pos', 'userquota_012_neg', + 'userspace_001_pos', 'userspace_002_pos'] +tags = ['functional', 'userquota'] + +[tests/functional/vdev_zaps] +tests = ['vdev_zaps_001_pos', 'vdev_zaps_002_pos', 'vdev_zaps_003_pos', + 'vdev_zaps_004_pos', 'vdev_zaps_005_pos', 'vdev_zaps_006_pos', + 'vdev_zaps_007_pos'] +tags = ['functional', 'vdev_zaps'] + +[tests/functional/write_dirs] +tests = ['write_dirs_001_pos', 'write_dirs_002_pos'] +tags = ['functional', 'write_dirs'] + +[tests/functional/xattr] +tests = ['xattr_001_pos', 'xattr_002_neg', 'xattr_003_neg', 'xattr_004_pos', + 'xattr_005_pos', 'xattr_006_pos', 'xattr_007_neg', + 'xattr_011_pos', 'xattr_012_pos', 'xattr_013_pos'] +tags = ['functional', 'xattr'] + +[tests/functional/zvol/zvol_ENOSPC] +tests = ['zvol_ENOSPC_001_pos'] +tags = ['functional', 'zvol', 'zvol_ENOSPC'] + +[tests/functional/zvol/zvol_cli] +tests = ['zvol_cli_001_pos', 'zvol_cli_002_pos', 'zvol_cli_003_neg'] +tags = ['functional', 'zvol', 'zvol_cli'] + +[tests/functional/zvol/zvol_misc] +tests = ['zvol_misc_002_pos', 'zvol_misc_hierarchy', 'zvol_misc_rename_inuse', + 'zvol_misc_snapdev', 'zvol_misc_volmode', 'zvol_misc_zil'] +tags = ['functional', 'zvol', 'zvol_misc'] + +[tests/functional/zvol/zvol_swap] +tests = ['zvol_swap_001_pos', 'zvol_swap_002_pos', 'zvol_swap_004_pos'] +tags = ['functional', 'zvol', 'zvol_swap'] + +[tests/functional/libzfs] +tests = ['many_fds', 'libzfs_input'] +tags = ['functional', 'libzfs'] + +[tests/functional/log_spacemap] +tests = ['log_spacemap_import_logs'] +pre = +post = +tags = ['functional', 'log_spacemap'] diff --git a/tests/runfiles/macOS-CI.run b/tests/runfiles/macOS-CI.run new file mode 100644 index 000000000000..7d2fa7fe62e3 --- /dev/null +++ b/tests/runfiles/macOS-CI.run @@ -0,0 +1,350 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +[DEFAULT] +pre = setup +quiet = False +pre_user = root +user = root +timeout = 600 +post_user = root +post = cleanup +failsafe_user = root +failsafe = callbacks/zfs_failsafe +outputdir = /var/tmp/test_results +tags = ['functional'] + +[tests/functional/checksum] +tests = ['run_sha2_test', 'run_skein_test', 'filetest_001_pos'] +tags = ['functional', 'checksum'] + +[tests/functional/clean_mirror] +tests = [ 'clean_mirror_001_pos', 'clean_mirror_002_pos', + 'clean_mirror_003_pos', 'clean_mirror_004_pos'] +tags = ['functional', 'clean_mirror'] + +[tests/functional/cli_root/zfs_bookmark] +tests = ['zfs_bookmark_cliargs'] +tags = ['functional', 'cli_root', 'zfs_bookmark'] + +[tests/functional/cli_root/zfs_change-key] +tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format', + 'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location', + 'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones'] +tags = ['functional', 'cli_root', 'zfs_change-key'] + +[tests/functional/cli_root/zfs_create] +tests = ['zfs_create_001_pos', +# 'zfs_create_002_pos', [02:08] + 'zfs_create_003_pos', + 'zfs_create_004_pos', 'zfs_create_005_pos', 'zfs_create_006_pos', + 'zfs_create_007_pos', 'zfs_create_008_neg', 'zfs_create_009_neg', + 'zfs_create_010_neg', 'zfs_create_011_pos', 'zfs_create_012_pos', +# 'zfs_create_013_pos', [02:10] + 'zfs_create_014_pos', 'zfs_create_encrypted', + 'zfs_create_crypt_combos', 'zfs_create_dryrun', 'zfs_create_verbose'] +tags = ['functional', 'cli_root', 'zfs_create'] + +[tests/functional/cli_root/zfs_diff] +tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp', + 'zfs_diff_types', 'zfs_diff_encrypted'] +tags = ['functional', 'cli_root', 'zfs_diff'] + +[tests/functional/cli_root/zfs_inherit] +tests = ['zfs_inherit_001_neg', 'zfs_inherit_002_neg', 'zfs_inherit_003_pos', + 'zfs_inherit_mountpoint'] +tags = ['functional', 'cli_root', 'zfs_inherit'] + +[tests/functional/cli_root/zfs_load-key] +tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file', + 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive'] +tags = ['functional', 'cli_root', 'zfs_load-key'] + +[tests/functional/cli_root/zfs_mount] +tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos', + 'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_007_pos', + 'zfs_mount_009_neg', 'zfs_mount_010_neg', 'zfs_mount_011_neg', + 'zfs_mount_012_pos', 'zfs_mount_all_001_pos', 'zfs_mount_encrypted', + 'zfs_mount_remount', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints', + 'zfs_mount_test_race'] +tags = ['functional', 'cli_root', 'zfs_mount'] + +[tests/functional/cli_root/zfs_property] +tests = ['zfs_written_property_001_pos'] +tags = ['functional', 'cli_root', 'zfs_property'] + +[tests/functional/cli_root/zfs_rollback] +tests = ['zfs_rollback_001_pos', 'zfs_rollback_002_pos', + 'zfs_rollback_003_neg', 'zfs_rollback_004_neg'] +tags = ['functional', 'cli_root', 'zfs_rollback'] + +[tests/functional/cli_root/zfs_send] +tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos', + 'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos', + 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw', + 'zfs_send_sparse', 'zfs_send-b'] +tags = ['functional', 'cli_root', 'zfs_send'] + +[tests/functional/cli_root/zfs_unload-key] +tests = ['zfs_unload-key', 'zfs_unload-key_all', 'zfs_unload-key_recursive'] +tags = ['functional', 'cli_root', 'zfs_unload-key'] + +[tests/functional/cli_root/zpool_attach] +tests = ['zpool_attach_001_neg', 'attach-o_ashift'] +tags = ['functional', 'cli_root', 'zpool_attach'] + +[tests/functional/cli_root/zpool_clear] +tests = ['zpool_clear_001_pos', 'zpool_clear_002_neg', 'zpool_clear_003_neg', + 'zpool_clear_readonly'] +tags = ['functional', 'cli_root', 'zpool_clear'] + +[tests/functional/cli_root/zpool_destroy] +tests = ['zpool_destroy_001_pos', 'zpool_destroy_002_pos', + 'zpool_destroy_003_neg'] +pre = +post = +tags = ['functional', 'cli_root', 'zpool_destroy'] + +[tests/functional/cli_root/zpool_detach] +tests = ['zpool_detach_001_neg'] +tags = ['functional', 'cli_root', 'zpool_detach'] + +[tests/functional/cli_root/zpool_export] +tests = ['zpool_export_001_pos', 'zpool_export_002_pos', + 'zpool_export_003_neg', 'zpool_export_004_pos'] +tags = ['functional', 'cli_root', 'zpool_export'] + +[tests/functional/cli_root/zpool_offline] +tests = ['zpool_offline_001_pos', 'zpool_offline_002_neg', + 'zpool_offline_003_pos'] +tags = ['functional', 'cli_root', 'zpool_offline'] + +[tests/functional/cli_root/zpool_online] +tests = ['zpool_online_001_pos', 'zpool_online_002_neg'] +tags = ['functional', 'cli_root', 'zpool_online'] + +[tests/functional/cli_root/zpool_remove] +tests = ['zpool_remove_001_neg', 'zpool_remove_002_pos', + 'zpool_remove_003_pos'] +tags = ['functional', 'cli_root', 'zpool_remove'] + +[tests/functional/cli_root/zpool_replace] +tests = ['zpool_replace_001_neg', 'replace-o_ashift', 'replace_prop_ashift'] +tags = ['functional', 'cli_root', 'zpool_replace'] + +[tests/functional/cli_root/zpool_resilver] +tests = ['zpool_resilver_bad_args', 'zpool_resilver_restart'] +tags = ['functional', 'cli_root', 'zpool_resilver'] + +[tests/functional/cli_root/zpool_scrub] +tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos', + 'zpool_scrub_004_pos', 'zpool_scrub_005_pos', + 'zpool_scrub_encrypted_unloaded', 'zpool_scrub_print_repairing', + 'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies'] +tags = ['functional', 'cli_root', 'zpool_scrub'] + +[tests/functional/cli_root/zpool_split] +tests = ['zpool_split_cliargs', 'zpool_split_devices', + 'zpool_split_encryption', 'zpool_split_props', 'zpool_split_vdevs', + 'zpool_split_resilver', 'zpool_split_indirect'] +tags = ['functional', 'cli_root', 'zpool_split'] + +[tests/functional/cli_root/zpool_status] +tests = ['zpool_status_001_pos', 'zpool_status_002_pos'] +tags = ['functional', 'cli_root', 'zpool_status'] + +[tests/functional/cli_root/zpool_sync] +tests = ['zpool_sync_001_pos', 'zpool_sync_002_neg'] +tags = ['functional', 'cli_root', 'zpool_sync'] + +[tests/functional/compression] +tests = ['compress_001_pos', 'compress_002_pos', 'compress_003_pos'] +tags = ['functional', 'compression'] + +[tests/functional/cp_files] +tests = ['cp_files_001_pos'] +tags = ['functional', 'cp_files'] + +[tests/functional/features/async_destroy] +tests = ['async_destroy_001_pos'] +tags = ['functional', 'features', 'async_destroy'] + +[tests/functional/features/large_dnode] +tests = ['large_dnode_001_pos', 'large_dnode_003_pos', 'large_dnode_004_neg', + 'large_dnode_005_pos', 'large_dnode_007_neg', 'large_dnode_009_pos'] +tags = ['functional', 'features', 'large_dnode'] + +[tests/functional/inuse] +tests = ['inuse_004_pos', 'inuse_005_pos', 'inuse_008_pos', 'inuse_009_pos'] +post = +tags = ['functional', 'inuse'] + +[tests/functional/large_files] +tests = ['large_files_001_pos', 'large_files_002_pos'] +tags = ['functional', 'large_files'] + +[tests/functional/largest_pool] +tests = ['largest_pool_001_pos'] +pre = +post = +tags = ['functional', 'largest_pool'] + +[tests/functional/mount] +tests = ['umount_001', 'umountall_001'] +tags = ['functional', 'mount'] + +[tests/functional/nestedfs] +tests = ['nestedfs_001_pos'] +tags = ['functional', 'nestedfs'] + +[tests/functional/no_space] +tests = ['enospc_001_pos', 'enospc_002_pos', 'enospc_003_pos', + 'enospc_df'] +tags = ['functional', 'no_space'] + +[tests/functional/nopwrite] +tests = ['nopwrite_copies', 'nopwrite_mtime', 'nopwrite_negative', + 'nopwrite_promoted_clone', 'nopwrite_recsize', 'nopwrite_sync', + 'nopwrite_varying_compression', 'nopwrite_volume'] +tags = ['functional', 'nopwrite'] + +[tests/functional/online_offline] +tests = ['online_offline_001_pos', 'online_offline_002_neg', + 'online_offline_003_neg'] +tags = ['functional', 'online_offline'] + +[tests/functional/poolversion] +tests = ['poolversion_001_pos', 'poolversion_002_pos'] +tags = ['functional', 'poolversion'] + +[tests/functional/quota] +tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', + 'quota_004_pos', 'quota_005_pos', 'quota_006_neg'] +tags = ['functional', 'quota'] + +[tests/functional/refquota] +tests = ['refquota_001_pos', 'refquota_002_pos', 'refquota_003_pos', + 'refquota_004_pos', 'refquota_005_pos', 'refquota_006_neg', + 'refquota_007_neg', 'refquota_008_neg'] +tags = ['functional', 'refquota'] + +[tests/functional/refreserv] +tests = ['refreserv_001_pos', 'refreserv_002_pos', 'refreserv_003_pos', + 'refreserv_004_pos', 'refreserv_005_pos', 'refreserv_multi_raidz', + 'refreserv_raidz'] +tags = ['functional', 'refreserv'] + +[tests/functional/removal] +pre = +tests = ['removal_all_vdev', 'removal_cancel', 'removal_check_space', + 'removal_condense_export', 'removal_multiple_indirection', + 'removal_nopwrite', 'removal_remap_deadlists', + 'removal_resume_export', 'removal_sanity', 'removal_with_add', + 'removal_with_create_fs', 'removal_with_dedup', + 'removal_with_errors', 'removal_with_export', + 'removal_with_ganging', 'removal_with_faulted', + 'removal_with_remove', 'removal_with_scrub', 'removal_with_send', + 'removal_with_send_recv', 'removal_with_snapshot', + 'removal_with_write', 'removal_with_zdb', 'remove_expanded', + 'remove_mirror', 'remove_mirror_sanity', 'remove_raidz', + 'remove_indirect'] +tags = ['functional', 'removal'] + +[tests/functional/resilver] +tests = ['resilver_restart_001', 'resilver_restart_002'] +tags = ['functional', 'resilver'] + +[tests/functional/rsend] +tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos', + 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'rsend_005_pos', + 'rsend_006_pos', 'rsend_007_pos', 'rsend_008_pos', 'rsend_009_pos', + 'rsend_010_pos', 'rsend_011_pos', 'rsend_012_pos', 'rsend_013_pos', + 'rsend_014_pos', 'rsend_016_neg', 'rsend_019_pos', 'rsend_020_pos', + 'rsend_021_pos', 'rsend_022_pos', 'rsend_024_pos', + 'send-c_verify_ratio', 'send-c_verify_contents', 'send-c_props', + 'send-c_incremental', 'send-c_volume', 'send-c_zstreamdump', + 'send-c_lz4_disabled', 'send-c_recv_lz4_disabled', + 'send-c_mixed_compression', 'send-c_stream_size_estimate', + 'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize', + 'send-c_recv_dedup', 'send-L_toggle', 'send_encrypted_hierarchy', + 'send_encrypted_props', 'send_encrypted_truncated_files', + 'send_freeobjects', 'send_realloc_files', + 'send_realloc_encrypted_files', 'send_spill_block', 'send_holds', + 'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol', + 'send_partial_dataset'] +tags = ['functional', 'rsend'] + +[tests/functional/scrub_mirror] +tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', + 'scrub_mirror_003_pos', 'scrub_mirror_004_pos'] +tags = ['functional', 'scrub_mirror'] + +[tests/functional/slog] +tests = ['slog_001_pos', 'slog_002_pos', 'slog_003_pos', 'slog_004_pos', + 'slog_005_pos', 'slog_006_pos', 'slog_007_pos', 'slog_008_neg', + 'slog_009_neg', 'slog_010_neg', 'slog_011_neg', 'slog_012_neg', + 'slog_013_pos', 'slog_014_pos', 'slog_015_neg', 'slog_replay_fs_001', + 'slog_replay_fs_002', 'slog_replay_volume'] +tags = ['functional', 'slog'] + +[tests/functional/snapshot] +tests = ['clone_001_pos', 'rollback_001_pos', 'rollback_002_pos', + 'rollback_003_pos', 'snapshot_001_pos', 'snapshot_002_pos', + 'snapshot_003_pos', 'snapshot_004_pos', 'snapshot_005_pos', + 'snapshot_006_pos', 'snapshot_007_pos', 'snapshot_008_pos', + 'snapshot_009_pos', 'snapshot_010_pos', 'snapshot_011_pos', + 'snapshot_012_pos', 'snapshot_013_pos', 'snapshot_014_pos', + 'snapshot_017_pos'] +tags = ['functional', 'snapshot'] + +[tests/functional/threadsappend] +tests = ['threadsappend_001_pos'] +tags = ['functional', 'threadsappend'] + +[tests/functional/upgrade] +tests = ['upgrade_userobj_001_pos', 'upgrade_readonly_pool'] +tags = ['functional', 'upgrade'] + +[tests/functional/userquota] +tests = [ + 'userquota_001_pos', 'userquota_002_pos', 'userquota_003_pos', + 'userquota_004_pos', 'userquota_005_neg', 'userquota_006_pos', + 'userquota_007_pos', 'userquota_008_pos', 'userquota_009_pos', + 'userquota_010_pos', 'userquota_011_pos', 'userquota_012_neg', + 'userspace_001_pos', 'userspace_002_pos'] +tags = ['functional', 'userquota'] + +[tests/functional/vdev_zaps] +tests = ['vdev_zaps_001_pos', 'vdev_zaps_002_pos', 'vdev_zaps_003_pos', + 'vdev_zaps_004_pos', 'vdev_zaps_005_pos', 'vdev_zaps_006_pos', + 'vdev_zaps_007_pos'] +tags = ['functional', 'vdev_zaps'] + +[tests/functional/xattr] +tests = ['xattr_001_pos', 'xattr_002_neg', 'xattr_003_neg', 'xattr_004_pos', + 'xattr_005_pos', 'xattr_006_pos', 'xattr_007_neg', + 'xattr_011_pos', 'xattr_012_pos', 'xattr_013_pos'] +tags = ['functional', 'xattr'] + +[tests/functional/zvol/zvol_cli] +tests = ['zvol_cli_001_pos', 'zvol_cli_002_pos', 'zvol_cli_003_neg'] +tags = ['functional', 'zvol', 'zvol_cli'] + +[tests/functional/zvol/zvol_misc] +tests = ['zvol_misc_002_pos', 'zvol_misc_hierarchy', 'zvol_misc_rename_inuse', + 'zvol_misc_snapdev', 'zvol_misc_volmode', 'zvol_misc_zil'] +tags = ['functional', 'zvol', 'zvol_misc'] + +[tests/functional/log_spacemap] +tests = ['log_spacemap_import_logs'] +pre = +post = +tags = ['functional', 'log_spacemap'] diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am index 9bdb3c209756..dd08b8d553ba 100644 --- a/tests/zfs-tests/cmd/Makefile.am +++ b/tests/zfs-tests/cmd/Makefile.am @@ -87,7 +87,9 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/send_doall libnvpair.la scripts_zfs_tests_bin_PROGRAMS += %D%/stride_dd +if !BUILD_MACOS %C%_stride_dd_LDADD = -lrt +endif scripts_zfs_tests_bin_PROGRAMS += %D%/threadsappend %C%_threadsappend_LDADD = -lpthread @@ -134,3 +136,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/randfree_file scripts_zfs_tests_bin_PROGRAMS += %D%/file_fadvise %C%_file_fadvise_SOURCES = %D%/file/file_fadvise.c endif + +if BUILD_MACOS +include $(srcdir)/%D%/librt/Makefile.am +endif diff --git a/tests/zfs-tests/cmd/checksum/blake3_test.c b/tests/zfs-tests/cmd/checksum/blake3_test.c index aebe0363cc6e..eadcb8a87446 100644 --- a/tests/zfs-tests/cmd/checksum/blake3_test.c +++ b/tests/zfs-tests/cmd/checksum/blake3_test.c @@ -452,11 +452,13 @@ static blake3_test_t TestArray[] = { } }; +#ifndef dprintf #ifdef BLAKE3_DEBUG #define dprintf printf #else #define dprintf(...) #endif +#endif static char fmt_tohex(char c); static size_t fmt_hexdump(char *dest, const char *src, size_t len); diff --git a/tests/zfs-tests/cmd/dosmode_readonly_write.c b/tests/zfs-tests/cmd/dosmode_readonly_write.c index 0441d1c7b472..d99f399ade9a 100644 --- a/tests/zfs-tests/cmd/dosmode_readonly_write.c +++ b/tests/zfs-tests/cmd/dosmode_readonly_write.c @@ -41,6 +41,12 @@ #include #endif +#ifdef __APPLE__ +#ifndef UF_READONLY +#define UF_READONLY UF_IMMUTABLE +#endif +#endif + int main(int argc, const char *argv[]) { @@ -56,6 +62,7 @@ main(int argc, const char *argv[]) fd = open(path, O_CREAT|O_RDWR, 0777); if (fd == -1) err(EXIT_FAILURE, "%s: open failed", path); + #ifdef __linux__ uint64_t dosflags = ZFS_READONLY; if (ioctl(fd, ZFS_IOC_SETDOSFLAGS, &dosflags) == -1) diff --git a/tests/zfs-tests/cmd/librt/Makefile.am b/tests/zfs-tests/cmd/librt/Makefile.am new file mode 100644 index 000000000000..9a6dcfd1cabb --- /dev/null +++ b/tests/zfs-tests/cmd/librt/Makefile.am @@ -0,0 +1,12 @@ + +lib_LTLIBRARIES += librt.la + +nodist_librt_la_SOURCES = \ + %D%/mach_gettime.c + +# We don't want .dylib, but .so.1 as it is hardcoded into test-runner.py +# -module -version-info produces librt.1.so (not .so.1 as we need) +librt_la_LDFLAGS=-module -avoid-version -shrext .so.1 + +#install-exec-local: librt_la +# ln -s diff --git a/tests/zfs-tests/cmd/librt/mach_gettime.c b/tests/zfs-tests/cmd/librt/mach_gettime.c new file mode 100644 index 000000000000..7f3fc0ba3e16 --- /dev/null +++ b/tests/zfs-tests/cmd/librt/mach_gettime.c @@ -0,0 +1,28 @@ +/* + * This relies on lib/libspl/include/os/macos/sys/time.h + * being included. + * Old macOS did not have clock_gettime, and current + * has it in libc. Linux assumes that we are to use + * librt for it, so we create this dummy library. + * The linker will sort out connecting it for us. + */ +#include +#include +#include +#include +#include +#include + +#if !defined(MAC_OS_X_VERSION_10_12) || \ + (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12) +extern int +clock_gettime(clock_id_t clock_id, struct timespec *tp); +#endif + +extern void gettime_dummy(void); + +void +gettime_dummy(void) +{ + clock_gettime(0, NULL); +} diff --git a/tests/zfs-tests/cmd/mmap_seek.c b/tests/zfs-tests/cmd/mmap_seek.c index 7be92d109565..77808a0abfad 100644 --- a/tests/zfs-tests/cmd/mmap_seek.c +++ b/tests/zfs-tests/cmd/mmap_seek.c @@ -38,23 +38,27 @@ static void seek_data(int fd, off_t offset, off_t expected) { +#if defined(SEEK_HOLE) && defined(SEEK_DATA) off_t data_offset = lseek(fd, offset, SEEK_DATA); if (data_offset != expected) { fprintf(stderr, "lseek(fd, %d, SEEK_DATA) = %d (expected %d)\n", (int)offset, (int)data_offset, (int)expected); exit(2); } +#endif } static void seek_hole(int fd, off_t offset, off_t expected) { +#if defined(SEEK_HOLE) && defined(SEEK_DATA) off_t hole_offset = lseek(fd, offset, SEEK_HOLE); if (hole_offset != expected) { fprintf(stderr, "lseek(fd, %d, SEEK_HOLE) = %d (expected %d)\n", (int)offset, (int)hole_offset, (int)expected); exit(2); } +#endif } int diff --git a/tests/zfs-tests/include/blkdev.shlib b/tests/zfs-tests/include/blkdev.shlib index 6b83b10d604d..93fa9dc7fdd8 100644 --- a/tests/zfs-tests/include/blkdev.shlib +++ b/tests/zfs-tests/include/blkdev.shlib @@ -84,6 +84,11 @@ function block_device_wait sysctl kern.geom.conftxt >/dev/null return fi + elif is_macos; then + if [[ ${#@} -eq 0 ]]; then + sleep 3 + return + fi fi # Poll for the given paths to appear, but give up eventually. typeset -i i @@ -123,6 +128,10 @@ function is_physical_device #device -e '^nda[0-9]+$' \ -e '^nvd[0-9]+$' \ -e '^vtbd[0-9]+$' + elif is_macos; then + is_disk_device "$DEV_DSKDIR/$device" && \ + echo $device | egrep -q \ + -e '^disk[0-9]+$' else echo $device | grep -qE "^c[0-F]+([td][0-F]+)+$" fi @@ -486,7 +495,7 @@ function get_pool_devices #testpool #devdir typeset out="" case "$UNAME" in - Linux|FreeBSD) + Linux|FreeBSD|Darwin) zpool status -P $testpool | awk -v d="$devdir" '$1 ~ d {sub(d "/", ""); printf("%s ", $1)}' ;; esac diff --git a/tests/zfs-tests/include/default.cfg.in b/tests/zfs-tests/include/default.cfg.in index 3aed8ebea03a..d1c9a7c0c2da 100644 --- a/tests/zfs-tests/include/default.cfg.in +++ b/tests/zfs-tests/include/default.cfg.in @@ -209,6 +209,22 @@ FreeBSD) NEWFS_DEFAULT_FS="ufs" SLICE_PREFIX="p" ;; +Darwin) + unpack_opts="xv" + pack_opts="cf" + verbose="v" + unpack_preserve="xpf" + pack_preserve="cpf" + + ZVOL_DEVDIR="/dev/zvol" + ZVOL_RDEVDIR="/dev/zvol" + DEV_DSKDIR="/dev" + DEV_RDSKDIR="/dev" + DEV_MPATHDIR="/dev/multipath" + + NEWFS_DEFAULT_FS="hfs" + SLICE_PREFIX="s" + ;; *) export AUTO_SNAP=$(svcs -a | \ awk '/auto-snapshot/ && /online/ { print $3 }') @@ -232,6 +248,22 @@ FreeBSD) NEWFS_DEFAULT_FS="ufs" SLICE_PREFIX="s" ;; +darwin) + unpack_opts="xv" + pack_opts="cf" + verbose="v" + unpack_preserve="xpf" + pack_preserve="cpf" + + ZVOL_DEVDIR="/var/run/zfs/" + ZVOL_RDEVDIR="/var/run/zfs/" + DEV_DSKDIR="/dev" + DEV_RDSKDIR="/dev" + DEV_MPATHDIR="/dev/multipath" + + NEWFS_DEFAULT_FS="hfs" + SLICE_PREFIX="s" + ;; esac export unpack_opts pack_opts verbose unpack_preserve pack_preserve \ ZVOL_DEVDIR ZVOL_RDEVDIR DEV_DSKDIR DEV_RDSKDIR DEV_MPATHDIR \ diff --git a/tests/zfs-tests/include/libtest.shlib b/tests/zfs-tests/include/libtest.shlib index 844caa17d8ed..34e2c6823dd0 100644 --- a/tests/zfs-tests/include/libtest.shlib +++ b/tests/zfs-tests/include/libtest.shlib @@ -103,6 +103,30 @@ function is_freebsd [ "$UNAME" = "FreeBSD" ] } +# Determine if this is a macOS test system +# +# Return 0 if platform macOS, 1 if otherwise + +function is_macos +{ + [ "$UNAME" = "Darwin" ] +} + +# Determine if this is a DilOS test system +# +# Return 0 if platform DilOS, 1 if otherwise + +function is_dilos +{ + typeset ID="" + [[ -f /etc/os-release ]] && . /etc/os-release + if [[ $ID == "dilos" ]]; then + return 0 + else + return 1 + fi +} + # Determine if this is a 32-bit system # # Return 0 if platform is 32-bit, 1 if otherwise @@ -162,6 +186,14 @@ function ismounted ext*) df -t $fstype $1 > /dev/null 2>&1 ;; + hfs) + out=$(df -T $fstype $1 | sed -e /^Filesystem/d 2>/dev/null) + ret=$? + (($ret != 0)) && return $ret + dir=$(echo $out | awk '{print $9}') + name=$(echo $out | awk '{print $1}') + [[ "$1" == "$dir" || "/private${1}" == "$dir" || "$1" == "$name" ]] && return 0 + ;; zvol) if [[ -L "$ZVOL_DEVDIR/$1" ]]; then link=$(readlink -f $ZVOL_DEVDIR/$1) @@ -751,6 +783,8 @@ function zero_partitions # if is_freebsd; then gpart destroy -F $diskname + elif is_macos; then + set_partition 0 "" 0mb $diskname elif is_linux; then DSK=$DEV_DSKDIR/$diskname DSK=$(echo $DSK | sed -e "s|//|/|g") @@ -861,6 +895,41 @@ function set_partition block_device_wait $disk ;; + + Darwin) + if [[ -z $size || -z $disk ]]; then + log_fail "The size or disk name is unspecified." + fi + log_note diskutil info $disk | grep "Block Size:" + typeset -i sector_size=$(diskutil info $disk | grep "Block Size:" | awk '{print $4}') + + # To create slice "0" erase this gpt, recreate, and add EFI partition. + if [[ $slicenum == 0 ]]; then + log_must gpt destroy $disk + log_must gpt create $disk + fi + + typeset size_mb=${size%%[mMgG]} + + size_mb=${size_mb%%[mMgG][bB]} + if [[ ${size:1:1} == 'g' ]]; then + ((size_mb = size_mb * 1024)) + fi + + typeset bytes + bytes=size_mb * 1024 + + # Dont create zero sized partitions + [[ $bytes == 0 ]] && return 0 + + # Convert to a sector count + typeset sectors=$(( $bytes / $sector_size )) + + # Add partition as "ZFS" - hopefully prevent DiskArbitrator popup. + log_must gpt add -s $sectors -t "6A898CC3-1DD2-11B2-99A6-080020736631" $disk + typeset ret_val=$? + ;; + *) if [[ -z $slicenum || -z $size || -z $disk ]]; then log_fail "The slice, size or disk name is unspecified." @@ -953,6 +1022,10 @@ function get_endslice # endcyl=$(gpart show $disk | \ awk -v slice=$slice '$3 == slice { print $1 + $2 }') ;; + Darwin) + # OSX we just append partitions, so return rubbish + endcyl=0; + ;; *) disk=${disk#/dev/dsk/} disk=${disk#/dev/rdsk/} @@ -990,6 +1063,15 @@ function partition_disk # typeset total_slices=$3 typeset cyl + if is_macos; then + #OSX we ignore the start cylinder and just let gpt add a new partition + while ((i < $total_slices)); do + set_partition $i "" $slice_size $disk_name + ((i = i+1)) + done + return + fi + zero_partitions $disk_name while ((i < $total_slices)); do if ! is_linux; then @@ -1154,6 +1236,24 @@ function is_shared_linux ! exportfs -s | awk -v fs="${fs//\\/\\\\}" '/^\// && $1 == fs {exit 1}' } +function is_shared_macos +{ + typeset fs=$1 + + for mtpt in `$CAT /etc/exports | $SED 's/\"//g' | $AWK '{ print $1 }'` ; do + if [[ $mtpt == $fs ]] ; then + log_note "filesystem ==>${fs}<== is shared" + return 0 + fi + done + + typeset stat=$(/sbin/nfsd status) + if ! [[ $stat =~ "enabled" ]]; then + log_note "Current nfs/server status: $stat" + fi + return 1 +} + # # Given a mountpoint, or a dataset name, determine if it is shared via NFS. # @@ -1181,6 +1281,7 @@ function is_shared case "$UNAME" in FreeBSD) is_shared_freebsd "$fs" ;; Linux) is_shared_linux "$fs" ;; + Darwin) is_shared_macos "$fs" ;; *) is_shared_illumos "$fs" ;; esac } @@ -1351,6 +1452,12 @@ function unshare_nfs #fs log_must mv /etc/zfs/exports.$$ /etc/zfs/exports log_must kill -s HUP "$mountd" ;; + Darwin) + /sbin/nfsd update + if [[ $? != 0 ]]; then + /sbin/nfsd start + fi + ;; *) log_must unshare -F nfs $fs ;; @@ -1404,6 +1511,11 @@ function setup_nfs_server return fi + if is_macos; then + /sbin/nfsd start + return + fi + if is_linux; then # # Re-synchronize /var/lib/nfs/etab with /etc/exports and @@ -1465,7 +1577,7 @@ function setup_nfs_server # function is_global_zone { - if is_linux || is_freebsd; then + if is_macos || is_linux || is_freebsd; then return 0 else typeset cur_zone=$(zonename 2>/dev/null) @@ -2072,7 +2184,7 @@ function cleanup_devices #vdevs function find_disks { # Trust provided list, no attempt is made to locate unused devices. - if is_linux || is_freebsd; then + if is_macos || is_linux || is_freebsd; then echo "$@" return fi @@ -2235,6 +2347,60 @@ function del_group_freebsd # return 0 } +function add_user_macos # +{ + typeset group=$1 + typeset user=$2 + typeset basedir=$3 + + # Find out the next available user ID + typeset -i maxid=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -ug | tail -1) + typeset -i userid=$((maxid+1)) + + # Create the user account by running dscl. + log_must dscl . -create /Users/$user + log_must dscl . -create /Users/$user UserShell /bin/bash + log_must dscl . -create /Users/$user RealName "$user" + log_must dscl . -create /Users/$user UniqueID "$userid" + log_must dscl . -create /Users/$user PrimaryGroupID 20 + log_must dscl . -create /Users/$user NFSHomeDirectory $basedir/$user + # log_must dscl . -passwd /Users/$user $password + + log_must dseditgroup -o edit -t user -a $user $group + + # Create the home directory + log_must createhomedir -l -u $user 2>&1 | grep -v "shell-init" + + return 0 +} + +function del_user_macos # +{ + typeset user=$1 + + if $ID $user > /dev/null 2>&1; then + log_must dscl . -delete /Users/$user + fi + + return 0 +} + +function add_group_macos # +{ + typeset group=$1 + + /usr/sbin/dseditgroup -o create $group + return 0 +} + +function del_group_macos # +{ + typeset group=$1 + + /usr/sbin/dseditgroup -o delete $group + return 0 +} + function add_user_illumos # { typeset group=$1 @@ -2368,6 +2534,9 @@ function add_user # Linux) add_user_linux "$group" "$user" "$basedir" ;; + Darwin) + add_user_macos "$group" "$user" "$basedir" + ;; *) add_user_illumos "$group" "$user" "$basedir" ;; @@ -2398,6 +2567,9 @@ function del_user # Linux) del_user_linux "$user" ;; + Darwin) + del_user_macos "$user" + ;; *) del_user_illumos "$user" ;; @@ -2428,6 +2600,9 @@ function add_group # Linux) add_group_linux "$group" ;; + Darwin) + add_group_macos "$group" + ;; *) add_group_illumos "$group" ;; @@ -2456,6 +2631,9 @@ function del_group # Linux) del_group_linux "$group" ;; + Darwin) + del_group_macos "$group" + ;; *) del_group_illumos "$group" ;; @@ -2800,6 +2978,8 @@ function get_num_cpus grep -c '^processor' /proc/cpuinfo elif is_freebsd; then sysctl -n kern.smp.cpus + elif is_macos; then + sysctl -n hw.ncpu else psrinfo | wc -l fi @@ -2813,7 +2993,9 @@ function is_mp function get_cpu_freq { - if is_linux; then + if is_macos; then + sysctl -n hw.cpufrequency + elif is_linux; then lscpu | awk '/CPU MHz/ { print $3 }' elif is_freebsd; then sysctl -n hw.clockrate @@ -2942,7 +3124,7 @@ function get_objnum typeset objnum [[ -e $pathname ]] || log_fail "No such file or directory: $pathname" - if is_freebsd; then + if is_freebsd || is_macos; then objnum=$(stat -f "%i" $pathname) else objnum=$(stat -c %i $pathname) @@ -3054,7 +3236,7 @@ function zed_rc_restore # $@ Optional list of zedlets to run under zed. function zed_setup { - if ! is_linux; then + if ! is_linux && ! is_macos; then log_unsupported "No zed on $UNAME" fi @@ -3101,7 +3283,7 @@ function zed_setup # $@ Optional list of zedlets to remove from our test zed.d directory. function zed_cleanup { - if ! is_linux; then + if ! is_linux && ! is_macos; then return fi @@ -3131,7 +3313,7 @@ function zed_check # function zed_start { - if ! is_linux; then + if ! is_linux && ! is_macos; then return fi @@ -3166,7 +3348,7 @@ function zed_start # function zed_stop { - if ! is_linux; then + if ! is_linux && ! is_macos; then return "" fi @@ -3228,10 +3410,16 @@ function is_swap_inuse FreeBSD) swapctl -l | grep -wq $device ;; + Darwin) + # No swap devices on macOS + true + ;; *) swap -l | grep -wq $device ;; esac + + return $? } # @@ -3249,6 +3437,8 @@ function swap_setup FreeBSD) log_must swapctl -a $swapdev ;; + Darwin) + ;; *) log_must swap -a $swapdev ;; @@ -3269,6 +3459,8 @@ function swap_cleanup log_must swapoff $swapdev elif is_freebsd; then log_must swapoff $swapdev + elif is_macos; then + return 0 else log_must swap -d $swapdev fi @@ -3328,6 +3520,10 @@ function set_tunable_impl FreeBSD) sysctl vfs.zfs.$tunable=$value ;; + Darwin) + sysctl kstat.zfs.darwin.tunable.$tunable=$value + return "$?" + ;; SunOS) echo "${tunable}/${mdb_cmd}0t${value}" | mdb -kw ;; @@ -3378,6 +3574,9 @@ function get_tunable_impl FreeBSD) sysctl -n vfs.zfs.$tunable ;; + Darwin) + sysctl -n kstat.zfs.darwin.tunable.$tunable + ;; SunOS) [[ "$module" -eq "zfs" ]] || return 1 ;; @@ -3404,6 +3603,9 @@ function md5digest FreeBSD) md5 -q $file ;; + Darwin) + md5 -q $file + ;; *) typeset sum _ read -r sum _ < <(md5sum -b $file) @@ -3424,6 +3626,9 @@ function sha256digest FreeBSD) sha256 -q $file ;; + Darwin) + shasum -a 256 -p $file + ;; *) typeset sum _ read -r sum _ < <(sha256sum -b $file) @@ -3438,6 +3643,9 @@ function new_fs # FreeBSD) newfs "$@" ;; + Darwin) + newfs_hfs "$@" + ;; *) echo y | newfs -v "$@" ;; @@ -3452,6 +3660,9 @@ function stat_size # FreeBSD) stat -f %z "$path" ;; + Darwin) + stat -f %z "$path" + ;; *) stat -c %s "$path" ;; @@ -3522,7 +3733,7 @@ function stat_generation # # function faketty { - if is_freebsd; then + if is_freebsd || is_macos; then script -q /dev/null env "$@" else script --return --quiet -c "$*" /dev/null @@ -3553,6 +3764,10 @@ function get_xattr # name path FreeBSD) getextattr -qq user "${name}" "${path}" ;; + Darwin) + xattr -px "${name}" "${path}" > /dev/null && + xattr -px "${name}" "${path}" | xxd -r -p + ;; *) attr -qg "${name}" "${path}" ;; @@ -3569,6 +3784,9 @@ function set_xattr # name value path FreeBSD) setextattr user "${name}" "${value}" "${path}" ;; + Darwin) + xattr -wx "${name}" "`echo ${value} | xxd -p -`" "${path}" + ;; *) attr -qs "${name}" -V "${value}" "${path}" ;; @@ -3584,6 +3802,9 @@ function set_xattr_stdin # name value FreeBSD) setextattr -i user "${name}" "${path}" ;; + Darwin) + xattr -wx "${name}" "`xxd -p -`" "${path}" + ;; *) attr -qs "${name}" "${path}" ;; @@ -3599,6 +3820,9 @@ function rm_xattr # name path FreeBSD) rmextattr -q user "${name}" "${path}" ;; + Darwin) + xattr -d "${name}" "${path}" + ;; *) attr -qr "${name}" "${path}" ;; @@ -3613,6 +3837,9 @@ function ls_xattr # path FreeBSD) lsextattr -qq user "${path}" ;; + Darwin) + xattr "${path}" + ;; *) attr -ql "${path}" ;; @@ -3645,6 +3872,9 @@ function get_arcstat # stat FreeBSD) kstat arcstats.$stat ;; + Darwin) + sysctl -n kstat.zfs.misc.arcstats.$stat + ;; Linux) kstat arcstats | awk "/$stat/"' { print $3 }' ;; @@ -3848,6 +4078,10 @@ function push_coredump_pattern # dir sysctl -n kern.corefile sysctl kern.corefile="$1/core.%N" >/dev/null ;; + Darwin) + sysctl -n kern.corefile + sysctl kern.corefile="$1/core.%N" >/dev/null + ;; *) # Nothing to output – set only for this shell coreadm -p "$1/core.%f" @@ -3871,5 +4105,42 @@ function pop_coredump_pattern FreeBSD) sysctl kern.corefile="$(<"$1")" >/dev/null ;; + Darwin) + sysctl kern.corefile="$(<"$1")" >/dev/null + ;; esac } + +function disable_spotlight # pool +{ + if is_macos; then + typeset pool=$1 + typeset mntpnt=$(get_prop mountpoint $pool) + mdutil -i off $mntpnt + mdutil -E $mntpnt + fi +} + +function enable_spotlight # pool +{ + if is_macos; then + typeset pool=$1 + typeset mntpnt=$(get_prop mountpoint $pool) + mdutil -i on $mntpnt + mdutil -E $mntpnt + fi +} + +function disable_mds +{ + if is_macos; then + launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist + fi +} + +function enable_mds +{ + if is_macos; then + launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist + fi +} diff --git a/tests/zfs-tests/include/tunables.cfg b/tests/zfs-tests/include/tunables.cfg index 80e7bcb3bd09..c17a213a25df 100644 --- a/tests/zfs-tests/include/tunables.cfg +++ b/tests/zfs-tests/include/tunables.cfg @@ -14,88 +14,88 @@ UNAME=$(uname) -# NAME FreeBSD tunable Linux tunable +# NAME FreeBSD tunable Linux tunable macOS tunable cat <<%%%% | -ADMIN_SNAPSHOT UNSUPPORTED zfs_admin_snapshot -ALLOW_REDACTED_DATASET_MOUNT allow_redacted_dataset_mount zfs_allow_redacted_dataset_mount -ARC_MAX arc.max zfs_arc_max -ARC_MIN arc.min zfs_arc_min -ASYNC_BLOCK_MAX_BLOCKS async_block_max_blocks zfs_async_block_max_blocks -CHECKSUM_EVENTS_PER_SECOND checksum_events_per_second zfs_checksum_events_per_second -COMMIT_TIMEOUT_PCT commit_timeout_pct zfs_commit_timeout_pct -COMPRESSED_ARC_ENABLED compressed_arc_enabled zfs_compressed_arc_enabled -CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS condense.indirect_commit_entry_delay_ms zfs_condense_indirect_commit_entry_delay_ms -CONDENSE_INDIRECT_OBSOLETE_PCT condense.indirect_obsolete_pct zfs_condense_indirect_obsolete_pct -CONDENSE_MIN_MAPPING_BYTES condense.min_mapping_bytes zfs_condense_min_mapping_bytes -DBUF_CACHE_SHIFT dbuf.cache_shift dbuf_cache_shift -DEADMAN_CHECKTIME_MS deadman.checktime_ms zfs_deadman_checktime_ms -DEADMAN_FAILMODE deadman.failmode zfs_deadman_failmode -DEADMAN_SYNCTIME_MS deadman.synctime_ms zfs_deadman_synctime_ms -DEADMAN_ZIOTIME_MS deadman.ziotime_ms zfs_deadman_ziotime_ms -DISABLE_IVSET_GUID_CHECK disable_ivset_guid_check zfs_disable_ivset_guid_check -DMU_OFFSET_NEXT_SYNC dmu_offset_next_sync zfs_dmu_offset_next_sync -INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size -INITIALIZE_VALUE initialize_value zfs_initialize_value -KEEP_LOG_SPACEMAPS_AT_EXPORT keep_log_spacemaps_at_export zfs_keep_log_spacemaps_at_export -LUA_MAX_MEMLIMIT lua.max_memlimit zfs_lua_max_memlimit -L2ARC_MFUONLY l2arc.mfuonly l2arc_mfuonly -L2ARC_NOPREFETCH l2arc.noprefetch l2arc_noprefetch -L2ARC_REBUILD_BLOCKS_MIN_L2SIZE l2arc.rebuild_blocks_min_l2size l2arc_rebuild_blocks_min_l2size -L2ARC_REBUILD_ENABLED l2arc.rebuild_enabled l2arc_rebuild_enabled -L2ARC_TRIM_AHEAD l2arc.trim_ahead l2arc_trim_ahead -L2ARC_WRITE_BOOST l2arc.write_boost l2arc_write_boost -L2ARC_WRITE_MAX l2arc.write_max l2arc_write_max -LIVELIST_CONDENSE_NEW_ALLOC livelist.condense.new_alloc zfs_livelist_condense_new_alloc -LIVELIST_CONDENSE_SYNC_CANCEL livelist.condense.sync_cancel zfs_livelist_condense_sync_cancel -LIVELIST_CONDENSE_SYNC_PAUSE livelist.condense.sync_pause zfs_livelist_condense_sync_pause -LIVELIST_CONDENSE_ZTHR_CANCEL livelist.condense.zthr_cancel zfs_livelist_condense_zthr_cancel -LIVELIST_CONDENSE_ZTHR_PAUSE livelist.condense.zthr_pause zfs_livelist_condense_zthr_pause -LIVELIST_MAX_ENTRIES livelist.max_entries zfs_livelist_max_entries -LIVELIST_MIN_PERCENT_SHARED livelist.min_percent_shared zfs_livelist_min_percent_shared -MAX_DATASET_NESTING max_dataset_nesting zfs_max_dataset_nesting -MAX_MISSING_TVDS max_missing_tvds zfs_max_missing_tvds -METASLAB_DEBUG_LOAD metaslab.debug_load metaslab_debug_load -METASLAB_FORCE_GANGING metaslab.force_ganging metaslab_force_ganging -MULTIHOST_FAIL_INTERVALS multihost.fail_intervals zfs_multihost_fail_intervals -MULTIHOST_HISTORY multihost.history zfs_multihost_history -MULTIHOST_IMPORT_INTERVALS multihost.import_intervals zfs_multihost_import_intervals -MULTIHOST_INTERVAL multihost.interval zfs_multihost_interval -OVERRIDE_ESTIMATE_RECORDSIZE send.override_estimate_recordsize zfs_override_estimate_recordsize -PREFETCH_DISABLE prefetch.disable zfs_prefetch_disable -REBUILD_SCRUB_ENABLED rebuild_scrub_enabled zfs_rebuild_scrub_enabled -REMOVAL_SUSPEND_PROGRESS removal_suspend_progress zfs_removal_suspend_progress -REMOVE_MAX_SEGMENT remove_max_segment zfs_remove_max_segment -RESILVER_MIN_TIME_MS resilver_min_time_ms zfs_resilver_min_time_ms -SCAN_LEGACY scan_legacy zfs_scan_legacy -SCAN_SUSPEND_PROGRESS scan_suspend_progress zfs_scan_suspend_progress -SCAN_VDEV_LIMIT scan_vdev_limit zfs_scan_vdev_limit -SEND_HOLES_WITHOUT_BIRTH_TIME send_holes_without_birth_time send_holes_without_birth_time -SLOW_IO_EVENTS_PER_SECOND slow_io_events_per_second zfs_slow_io_events_per_second -SPA_ASIZE_INFLATION spa.asize_inflation spa_asize_inflation -SPA_DISCARD_MEMORY_LIMIT spa.discard_memory_limit zfs_spa_discard_memory_limit -SPA_LOAD_VERIFY_DATA spa.load_verify_data spa_load_verify_data -SPA_LOAD_VERIFY_METADATA spa.load_verify_metadata spa_load_verify_metadata -TRIM_EXTENT_BYTES_MIN trim.extent_bytes_min zfs_trim_extent_bytes_min -TRIM_METASLAB_SKIP trim.metaslab_skip zfs_trim_metaslab_skip -TRIM_TXG_BATCH trim.txg_batch zfs_trim_txg_batch -TXG_HISTORY txg.history zfs_txg_history -TXG_TIMEOUT txg.timeout zfs_txg_timeout -UNLINK_SUSPEND_PROGRESS UNSUPPORTED zfs_unlink_suspend_progress -VDEV_FILE_LOGICAL_ASHIFT vdev.file.logical_ashift vdev_file_logical_ashift -VDEV_FILE_PHYSICAL_ASHIFT vdev.file.physical_ashift vdev_file_physical_ashift -VDEV_MAX_AUTO_ASHIFT vdev.max_auto_ashift zfs_vdev_max_auto_ashift -VDEV_MIN_MS_COUNT vdev.min_ms_count zfs_vdev_min_ms_count -VDEV_VALIDATE_SKIP vdev.validate_skip vdev_validate_skip -VOL_INHIBIT_DEV UNSUPPORTED zvol_inhibit_dev -VOL_MODE vol.mode zvol_volmode -VOL_RECURSIVE vol.recursive UNSUPPORTED -VOL_USE_BLK_MQ UNSUPPORTED zvol_use_blk_mq -XATTR_COMPAT xattr_compat zfs_xattr_compat -ZEVENT_LEN_MAX zevent.len_max zfs_zevent_len_max -ZEVENT_RETAIN_MAX zevent.retain_max zfs_zevent_retain_max -ZIO_SLOW_IO_MS zio.slow_io_ms zio_slow_io_ms -ZIL_SAXATTR zil_saxattr zfs_zil_saxattr +ADMIN_SNAPSHOT UNSUPPORTED zfs_admin_snapshot zfs_admin_snapshot +ALLOW_REDACTED_DATASET_MOUNT allow_redacted_dataset_mount zfs_allow_redacted_dataset_mount zfs.allow_redacted_dataset_mount +ARC_MAX arc.max zfs_arc_max zfs_arc.max +ARC_MIN arc.min zfs_arc_min zfs_arc.min +ASYNC_BLOCK_MAX_BLOCKS async_block_max_blocks zfs_async_block_max_blocks zfs.async_block_max_blocks +CHECKSUM_EVENTS_PER_SECOND checksum_events_per_second zfs_checksum_events_per_second zfs.checksum_events_per_second +COMMIT_TIMEOUT_PCT commit_timeout_pct zfs_commit_timeout_pct zfs.commit_timeout_pct +COMPRESSED_ARC_ENABLED compressed_arc_enabled zfs_compressed_arc_enabled zfs.compressed_arc_enabled +CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS condense.indirect_commit_entry_delay_ms zfs_condense_indirect_commit_entry_delay_ms zfs_condense.indirect_commit_entry_delay_ms +CONDENSE_INDIRECT_OBSOLETE_PCT condense.indirect_obsolete_pct zfs_condense_indirect_obsolete_pct zfs_condense.indirect_obsolete_pct +CONDENSE_MIN_MAPPING_BYTES condense.min_mapping_bytes zfs_condense_min_mapping_bytes zfs_condense.min_mapping_bytes +DBUF_CACHE_SHIFT dbuf.cache_shift dbuf_cache_shift zfs_dbuf.cache_shift +DEADMAN_CHECKTIME_MS deadman.checktime_ms zfs_deadman_checktime_ms zfs_deadman.checktime_ms +DEADMAN_FAILMODE deadman.failmode zfs_deadman_failmode zfs_deadman.failmode +DEADMAN_SYNCTIME_MS deadman.synctime_ms zfs_deadman_synctime_ms zfs_deadman.synctime_ms +DEADMAN_ZIOTIME_MS deadman.ziotime_ms zfs_deadman_ziotime_ms zfs_deadman.ziotime_ms +DISABLE_IVSET_GUID_CHECK disable_ivset_guid_check zfs_disable_ivset_guid_check zfs.disable_ivset_guid_check +DMU_OFFSET_NEXT_SYNC dmu_offset_next_sync zfs_dmu_offset_next_sync zfs.dmu_offset_next_sync +INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size zfs.initialize_chunk_size +INITIALIZE_VALUE initialize_value zfs_initialize_value zfs.initialize_value +KEEP_LOG_SPACEMAPS_AT_EXPORT keep_log_spacemaps_at_export zfs_keep_log_spacemaps_at_export zfs.keep_log_spacemaps_at_export +LUA_MAX_MEMLIMIT lua.max_memlimit zfs_lua_max_memlimit zfs_lua.max_memlimit +L2ARC_MFUONLY l2arc.mfuonly l2arc_mfuonly zfs_l2arc.mfuonly +L2ARC_NOPREFETCH l2arc.noprefetch l2arc_noprefetch zfs_l2arc.noprefetch +L2ARC_REBUILD_BLOCKS_MIN_L2SIZE l2arc.rebuild_blocks_min_l2size l2arc_rebuild_blocks_min_l2size zfs_l2arc.rebuild_blocks_min_l2size +L2ARC_REBUILD_ENABLED l2arc.rebuild_enabled l2arc_rebuild_enabled zfs_l2arc.rebuild_enabled +L2ARC_TRIM_AHEAD l2arc.trim_ahead l2arc_trim_ahead zfs_l2arc.trim_ahead +L2ARC_WRITE_BOOST l2arc.write_boost l2arc_write_boost zfs_l2arc.write_boost +L2ARC_WRITE_MAX l2arc.write_max l2arc_write_max zfs_l2arc.write_max +LIVELIST_CONDENSE_NEW_ALLOC livelist.condense.new_alloc zfs_livelist_condense_new_alloc zfs_livelist.condense.new_alloc +LIVELIST_CONDENSE_SYNC_CANCEL livelist.condense.sync_cancel zfs_livelist_condense_sync_cancel zfs_livelist.condense.sync_cancel +LIVELIST_CONDENSE_SYNC_PAUSE livelist.condense.sync_pause zfs_livelist_condense_sync_pause zfs.livelist.condense_sync_pause +LIVELIST_CONDENSE_ZTHR_CANCEL livelist.condense.zthr_cancel zfs_livelist_condense_zthr_cancel zfs.livelist.condense_zthr_cancel +LIVELIST_CONDENSE_ZTHR_PAUSE livelist.condense.zthr_pause zfs_livelist_condense_zthr_pause zfs.livelist.condense_zthr_pause +LIVELIST_MAX_ENTRIES livelist.max_entries zfs_livelist_max_entries zfs.livelist.max_entries +LIVELIST_MIN_PERCENT_SHARED livelist.min_percent_shared zfs_livelist_min_percent_shared zfs.livelist.min_percent_shared +MAX_DATASET_NESTING max_dataset_nesting zfs_max_dataset_nesting zfs.max_dataset_nesting +MAX_MISSING_TVDS max_missing_tvds zfs_max_missing_tvds zfs.max_missing_tvds +METASLAB_DEBUG_LOAD metaslab.debug_load metaslab_debug_load zfs_metaslab.debug_load +METASLAB_FORCE_GANGING metaslab.force_ganging metaslab_force_ganging zfs_metaslab.force_ganging +MULTIHOST_FAIL_INTERVALS multihost.fail_intervals zfs_multihost_fail_intervals zfs_multihost.fail_intervals +MULTIHOST_HISTORY multihost.history zfs_multihost_history zfs_multihost.history +MULTIHOST_IMPORT_INTERVALS multihost.import_intervals zfs_multihost_import_intervals zfs_multihost.import_intervals +MULTIHOST_INTERVAL multihost.interval zfs_multihost_interval zfs_multihost.interval +OVERRIDE_ESTIMATE_RECORDSIZE send.override_estimate_recordsize zfs_override_estimate_recordsize zfs_send.override_estimate_recordsize +PREFETCH_DISABLE prefetch.disable zfs_prefetch_disable zfs_prefetch.disable +REBUILD_SCRUB_ENABLED rebuild_scrub_enabled zfs_rebuild_scrub_enabled zfs.rebuild_scrub_enabled +REMOVAL_SUSPEND_PROGRESS removal_suspend_progress zfs_removal_suspend_progress zfs_vdev.removal_suspend_progress +REMOVE_MAX_SEGMENT remove_max_segment zfs_remove_max_segment zfs_vdev.remove_max_segment +RESILVER_MIN_TIME_MS resilver_min_time_ms zfs_resilver_min_time_ms zfs.resilver_min_time_ms +SCAN_LEGACY scan_legacy zfs_scan_legacy zfs.scan_legacy +SCAN_SUSPEND_PROGRESS scan_suspend_progress zfs_scan_suspend_progress zfs.scan_suspend_progress +SCAN_VDEV_LIMIT scan_vdev_limit zfs_scan_vdev_limit zfs.scan_vdev_limit +SEND_HOLES_WITHOUT_BIRTH_TIME send_holes_without_birth_time send_holes_without_birth_time zfs.send_holes_without_birth_time +SLOW_IO_EVENTS_PER_SECOND slow_io_events_per_second zfs_slow_io_events_per_second zfs.slow_io_events_per_second +SPA_ASIZE_INFLATION spa.asize_inflation spa_asize_inflation zfs_spa.asize_inflation +SPA_DISCARD_MEMORY_LIMIT spa.discard_memory_limit zfs_spa_discard_memory_limit zfs_spa.discard_memory_limit +SPA_LOAD_VERIFY_DATA spa.load_verify_data spa_load_verify_data zfs_spa.load_verify_data +SPA_LOAD_VERIFY_METADATA spa.load_verify_metadata spa_load_verify_metadata zfs_spa.load_verify_metadata +TRIM_EXTENT_BYTES_MIN trim.extent_bytes_min zfs_trim_extent_bytes_min zfs_trim.extent_bytes_min +TRIM_METASLAB_SKIP trim.metaslab_skip zfs_trim_metaslab_skip zfs_trim.metaslab_skip +TRIM_TXG_BATCH trim.txg_batch zfs_trim_txg_batch zfs_trim.txg_batch +TXG_HISTORY txg.history zfs_txg_history zfs_txg.history +TXG_TIMEOUT txg.timeout zfs_txg_timeout zfs_txg.timeout +UNLINK_SUSPEND_PROGRESS UNSUPPORTED zfs_unlink_suspend_progress UNSUPPORTED +VDEV_FILE_LOGICAL_ASHIFT vdev.file.logical_ashift vdev_file_logical_ashift UNSUPPORTED +VDEV_FILE_PHYSICAL_ASHIFT vdev.file.physical_ashift vdev_file_physical_ashift UNSUPPORTED +VDEV_MAX_AUTO_ASHIFT vdev.max_auto_ashift zfs_vdev_max_auto_ashift zfs_vdev.max_auto_ashift +VDEV_MIN_MS_COUNT vdev.min_ms_count zfs_vdev_min_ms_count zfs_vdev.min_ms_count +VDEV_VALIDATE_SKIP vdev.validate_skip vdev_validate_skip zfs_vdev.validate_skip +VOL_INHIBIT_DEV UNSUPPORTED zvol_inhibit_dev UNSUPPORTED +VOL_MODE vol.mode zvol_volmode UNSUPPORTED +VOL_RECURSIVE vol.recursive UNSUPPORTED UNSUPPORTED +VOL_USE_BLK_MQ UNSUPPORTED zvol_use_blk_mq UNSUPPORTED +XATTR_COMPAT xattr_compat zfs_xattr_compat UNSUPPORTED +ZEVENT_LEN_MAX zevent.len_max zfs_zevent_len_max zfs_zevent.len_max +ZEVENT_RETAIN_MAX zevent.retain_max zfs_zevent_retain_max zfs_zevent.retain_max +ZIO_SLOW_IO_MS zio.slow_io_ms zio_slow_io_ms zfs_zio.slow_io_ms +ZIL_SAXATTR zil_saxattr zfs_zil_saxattr zfs.zil_saxattr %%%% -while read name FreeBSD Linux; do +while read name FreeBSD Linux Darwin; do eval "export ${name}=\$${UNAME}" done diff --git a/tests/zfs-tests/tests/functional/hkdf/hkdf_test.c b/tests/zfs-tests/tests/functional/hkdf/hkdf_test.c index 24aeb0b224a7..a8ca346b9087 100644 --- a/tests/zfs-tests/tests/functional/hkdf/hkdf_test.c +++ b/tests/zfs-tests/tests/functional/hkdf/hkdf_test.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Byte arrays are given as char pointers so that they diff --git a/tests/zfs-tests/tests/perf/perf.shlib b/tests/zfs-tests/tests/perf/perf.shlib index 5555e910d722..eeb718f80a2b 100644 --- a/tests/zfs-tests/tests/perf/perf.shlib +++ b/tests/zfs-tests/tests/perf/perf.shlib @@ -387,6 +387,9 @@ function get_min_arc_size FreeBSD) sysctl -n kstat.zfs.misc.arcstats.c_min ;; + Darwin) + sysctl -n kstat.zfs.misc.arcstats.c_min + ;; *) dtrace -qn 'BEGIN { printf("%u\n", `arc_stats.arcstat_c_min.value.ui64); @@ -405,6 +408,9 @@ function get_max_arc_size FreeBSD) sysctl -n kstat.zfs.misc.arcstats.c_max ;; + Darwin) + sysctl -n kstat.zfs.misc.arcstats.c_max + ;; *) dtrace -qn 'BEGIN { printf("%u\n", `arc_stats.arcstat_c_max.value.ui64); @@ -423,6 +429,9 @@ function get_arc_target FreeBSD) sysctl -n kstat.zfs.misc.arcstats.c ;; + Darwin) + sysctl -n kstat.zfs.misc.arcstats.c + ;; *) dtrace -qn 'BEGIN { printf("%u\n", `arc_stats.arcstat_c.value.ui64);