From 5823727447c8967299c663c5a8736027c9e4eb08 Mon Sep 17 00:00:00 2001 From: Andrew Innes Date: Tue, 14 Nov 2023 16:32:17 +0800 Subject: [PATCH] non macos changes --- cmd/zdb/zdb.c | 8 +- cmd/zed/agents/fmd_api.h | 2 +- cmd/zfs/zfs_main.c | 58 ++++++- cmd/zpool/zpool_vdev.c | 29 +++- include/libzfs.h | 17 ++ include/libzutil.h | 4 + include/os/freebsd/spl/sys/simd_aarch64.h | 9 ++ include/os/linux/kernel/linux/simd_aarch64.h | 10 ++ include/os/linux/zfs/sys/zfs_context_os.h | 4 + include/sys/abd.h | 9 +- include/sys/abd_impl.h | 3 + include/sys/asm_linkage.h | 4 + include/sys/crypto/icp.h | 3 + include/sys/mntent.h | 7 + include/sys/spa.h | 2 + include/sys/spa_impl.h | 3 + include/sys/sysevent/dev.h | 2 +- include/sys/vdev_raidz.h | 1 + include/sys/xvattr.h | 12 +- include/sys/zfs_bootenv.h | 1 + include/sys/zfs_debug.h | 21 ++- include/sys/zfs_file.h | 2 + include/sys/zfs_ioctl_impl.h | 3 + include/sys/zfs_sa.h | 10 ++ include/sys/zfs_znode.h | 3 + include/sys/zio.h | 4 + include/sys/zio_crypt.h | 5 + include/zfs_fletcher.h | 1 + lib/libspl/atomic.c | 8 +- lib/libspl/include/sys/asm_linkage.h | 5 +- lib/libspl/include/sys/dkio.h | 2 + lib/libspl/include/sys/isa_defs.h | 3 + lib/libspl/include/sys/simd.h | 32 ++++ lib/libspl/include/sys/uio.h | 6 +- lib/libzfs/libzfs_crypto.c | 2 + lib/libzfs/libzfs_dataset.c | 62 ++++++++ lib/libzfs/libzfs_diff.c | 5 + lib/libzfs/libzfs_iter.c | 16 +- lib/libzfs/libzfs_sendrecv.c | 27 ++++ lib/libzfs_core/libzfs_core.c | 3 + lib/libzutil/zutil_device_path.c | 40 ++++- lib/libzutil/zutil_import.c | 17 ++ lib/libzutil/zutil_pool.c | 1 + module/icp/algs/aes/aes_impl.c | 40 ++++- module/icp/algs/aes/aes_impl_aesv8.c | 146 ++++++++++++++++++ module/icp/algs/blake3/blake3_impl.c | 16 +- module/icp/algs/modes/gcm.c | 77 ++++++++- module/icp/algs/sha2/sha256_impl.c | 9 +- module/icp/algs/sha2/sha512_impl.c | 9 +- module/icp/core/kcf_mech_tabs.c | 1 + module/icp/include/aes/aes_impl.h | 4 + module/lua/ldo.c | 2 +- module/nvpair/nvpair.c | 28 ++++ module/zcommon/zfeature_common.c | 9 +- module/zcommon/zfs_fletcher.c | 12 +- module/zcommon/zfs_prop.c | 34 ++++ module/zcommon/zprop_common.c | 3 +- module/zfs/blake3_zfs.c | 5 +- module/zfs/dbuf.c | 23 +++ module/zfs/dsl_crypt.c | 16 ++ module/zfs/dsl_scan.c | 5 + module/zfs/spa.c | 25 ++- module/zfs/spa_errlog.c | 2 +- module/zfs/spa_misc.c | 2 +- module/zfs/vdev_raidz_math.c | 30 +++- module/zfs/zfs_fuid.c | 17 ++ module/zfs/zfs_ioctl.c | 2 +- module/zfs/zfs_log.c | 22 +++ module/zfs/zfs_sa.c | 2 + module/zfs/zvol.c | 2 +- module/zstd/include/limits.h | 1 + module/zstd/include/stddef.h | 1 + module/zstd/include/stdint.h | 1 + module/zstd/include/string.h | 1 + module/zstd/lib/common/zstd_internal.h | 8 +- tests/zfs-tests/cmd/checksum/blake3_test.c | 2 + tests/zfs-tests/cmd/dosmode_readonly_write.c | 7 + tests/zfs-tests/cmd/librt/mach_gettime.c | 28 ++++ tests/zfs-tests/cmd/mmap_seek.c | 4 + .../tests/functional/hkdf/hkdf_test.c | 1 + 80 files changed, 999 insertions(+), 64 deletions(-) create mode 100644 module/icp/algs/aes/aes_impl_aesv8.c create mode 100644 tests/zfs-tests/cmd/librt/mach_gettime.c diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 18221c4b92d2..b7c4351414ad 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/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/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 9939f206a7f2..f86db5ed8424 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -789,7 +789,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); } @@ -1459,6 +1459,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) { @@ -4187,6 +4190,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); @@ -7285,6 +7293,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) { @@ -7302,6 +7343,7 @@ share_mount(int op, int argc, char **argv) zfs_commit_shares(NULL); zfs_close(zhp); } +#endif // !APPLE } free(options); @@ -7673,9 +7715,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/zpool_vdev.c b/cmd/zpool/zpool_vdev.c index fbd4b81dfacc..6bbf69340dd0 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/include/libzfs.h b/include/libzfs.h index dbb6340b0a43..4a4cb6b4356d 100644 --- a/include/libzfs.h +++ b/include/libzfs.h @@ -1004,6 +1004,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 @@ -1040,9 +1041,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 9842c225b6f0..b98fc3c20ed7 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); 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 b48dc36423f7..e119c99a6e7a 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/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 cef7933df441..99547da0e2e8 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -1149,6 +1149,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 ee91816ac48e..fcea60e0531d 100644 --- a/include/sys/spa_impl.h +++ b/include/sys/spa_impl.h @@ -455,6 +455,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 a34bc00ca4df..f2e75e3ca7c6 100644 --- a/include/sys/vdev_raidz.h +++ b/include/sys/vdev_raidz.h @@ -73,6 +73,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_expand { uint64_t vre_vdev_id; 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 8d94557a5882..0a84dcdab574 100644 --- a/include/sys/zfs_debug.h +++ b/include/sys/zfs_debug.h @@ -84,12 +84,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__) @@ -97,6 +112,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 d71144807f47..6c3c7603aaa9 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 25a4b221f05e..70e36d81471a 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -523,6 +523,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/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/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/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 727efc5a91ad..9a00bf9ec2f7 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 @@ -2219,6 +2220,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; } @@ -2255,6 +2268,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); @@ -2765,6 +2782,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); @@ -2772,6 +2816,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); @@ -3911,7 +3957,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/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index 01d803e21db0..1c4f3898a043 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/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/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..2cd0c67ce8b6 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 ((const 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..b791540b8f6b 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 ((const 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..9c5b3bbc6c37 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 ((const 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/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/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 309d9bf14cd4..9602db310ec1 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..fa8876ca503f 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 ((const 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 764993b45e7c..0b5789f7e5f2 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -398,6 +398,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, @@ -609,6 +625,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 0a179fffb16a..ddca747ea902 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 e16128fdff87..fbb2dfc5f519 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -3487,8 +3487,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/spa.c b/module/zfs/spa.c index 20225640f8c5..cd7f816dd172 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -1178,6 +1178,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 @@ -6422,12 +6443,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 5dd08f597f33..fc8336a8209b 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 3990af98c732..6a529f96ae4d 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -649,7 +649,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 b2b06881bdd4..bef6ac460d82 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -7042,7 +7042,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 433a653e5500..b42c2c866e16 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/zvol.c b/module/zfs/zvol.c index c7e10fbc638b..665458860b76 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/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 b45602d80651..0f79aede3d9a 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/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/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