From 5d42b2c93c8f8b415c2d741c7d1172b8defdefaa Mon Sep 17 00:00:00 2001 From: Sean Doran Date: Sat, 5 Mar 2022 10:18:20 +0000 Subject: [PATCH 1/5] smd: fix taskq_empty_ent IS_EMPTY macro does not catch case where tqent_prev and tqent_next are NULL --- module/os/macos/spl/spl-taskq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/os/macos/spl/spl-taskq.c b/module/os/macos/spl/spl-taskq.c index 7f8e57039..5bff27fb5 100644 --- a/module/os/macos/spl/spl-taskq.c +++ b/module/os/macos/spl/spl-taskq.c @@ -1684,7 +1684,10 @@ taskq_empty(taskq_t *tq) int taskq_empty_ent(taskq_ent_t *t) { - return (IS_EMPTY(*t)); + if (t->tqent_prev == NULL && t->tqent_next == NULL) + return (TRUE); + else + return (IS_EMPTY(*t)); } /* From cde6cbab5c4c3e63100c682ae6ba14ac241d5fcd Mon Sep 17 00:00:00 2001 From: Sean Doran Date: Sat, 12 Mar 2022 11:39:32 +0000 Subject: [PATCH 2/5] handle_sync_iokit: don't reuse lhp on failure, and allow paranoia Allow kstat.zfs.darwin.tunable.use_system_sync to control whether we use the post-10.11 IOKit barrier sync or not. Do not call the synchronize method a second time in the same invocation of handle_sync_iokit. Log the IOReturn error. --- module/os/macos/zfs/ldi_iokit.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/module/os/macos/zfs/ldi_iokit.cpp b/module/os/macos/zfs/ldi_iokit.cpp index 3699f391b..8f6c864f3 100644 --- a/module/os/macos/zfs/ldi_iokit.cpp +++ b/module/os/macos/zfs/ldi_iokit.cpp @@ -423,17 +423,19 @@ handle_sync_iokit(struct ldi_handle *lhp) #if defined(MAC_OS_X_VERSION_10_11) && \ (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) + /* from module/os/macos/zfs/zfs_vfsops.c */ + extern uint64_t zfs_vfs_sync_paranoia; /* Issue device sync */ - if (LH_MEDIA(lhp)->synchronize(LH_CLIENT(lhp), 0, 0, kIOStorageSynchronizeOptionBarrier) != - kIOReturnSuccess) { - printf("%s %s\n", __func__, - "IOMedia synchronizeCache (with write barrier) failed\n"); - if (LH_MEDIA(lhp)->synchronize(LH_CLIENT(lhp), 0, 0, 0) != - kIOReturnSuccess) { - printf("%s %s\n", __func__, - "IOMedia synchronizeCache (standard) failed\n"); - return (ENOTSUP); - } + IOStorageSynchronizeOptions synctype = (zfs_vfs_sync_paranoia != 0) + ? kIOStorageSynchronizeOptionNone + : kIOStorageSynchronizeOptionBarrier; + IOReturn ret = LH_MEDIA(lhp)->synchronize(LH_CLIENT(lhp), + 0, 0, synctype); + if (ret != kIOReturnSuccess) { + printf("%s %s %d %s\n", __func__, + "IOMedia synchronizeCache (with write barrier) failed", + ret, "(see IOReturn.h)\n"); + return (ENOTSUP); } #else /* Issue device sync */ From 00218f4d319dc02fa6ebe1b5949bdc7f08f8f0b3 Mon Sep 17 00:00:00 2001 From: Sean Doran Date: Wed, 17 Aug 2022 16:19:14 +0100 Subject: [PATCH 3/5] FUA on paranoia (kstat.zfs.darwin.tunable.use_system_sync!=0) If zfs_vfs_sync_paranoia is nonzero, then issue Forced Unit Access on ZIO_PRIORITY_SYNC_WRITE zios, which are generated for ZIL writes. --- module/os/macos/zfs/vdev_disk.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/module/os/macos/zfs/vdev_disk.c b/module/os/macos/zfs/vdev_disk.c index 5cc48ca3b..974c37e38 100644 --- a/module/os/macos/zfs/vdev_disk.c +++ b/module/os/macos/zfs/vdev_disk.c @@ -53,6 +53,8 @@ static void vdev_disk_close(vdev_t *); extern unsigned int spl_split_stack_below; +extern uint64_t zfs_vfs_sync_paranoia; + typedef struct vdev_disk_ldi_cb { list_node_t lcb_next; ldi_callback_id_t lcb_id; @@ -517,10 +519,13 @@ vdev_disk_io_strategy(void *arg) switch (zio->io_type) { case ZIO_TYPE_WRITE: - if (zio->io_priority == ZIO_PRIORITY_SYNC_WRITE) + if (zio->io_priority == ZIO_PRIORITY_SYNC_WRITE) { flags = B_WRITE; - else + if (zfs_vfs_sync_paranoia != 0) + flags |= B_FUA; + } else { flags = B_WRITE | B_ASYNC; + } bp->b_un.b_addr = abd_borrow_buf_copy(zio->io_abd, zio->io_size); From 34aa0063353b8efc4fc186df35e8b10a453e2df3 Mon Sep 17 00:00:00 2001 From: Sean Doran Date: Wed, 17 Aug 2022 18:26:43 +0100 Subject: [PATCH 4/5] build fix: missing-prototypes Werror for gettime_dummy() --- tests/zfs-tests/cmd/librt/mach_gettime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/zfs-tests/cmd/librt/mach_gettime.c b/tests/zfs-tests/cmd/librt/mach_gettime.c index 8dea325da..ef32496cb 100644 --- a/tests/zfs-tests/cmd/librt/mach_gettime.c +++ b/tests/zfs-tests/cmd/librt/mach_gettime.c @@ -12,6 +12,8 @@ #include #include +void gettime_dummy(void); + extern int clock_gettime(clock_id_t clock_id, struct timespec *tp); From cd521b2689878036b775b7b821a2908e443d1c51 Mon Sep 17 00:00:00 2001 From: Sean Doran Date: Wed, 17 Aug 2022 18:46:54 +0100 Subject: [PATCH 5/5] TEST COMMIT: paranoia = on This is just to run the tests with these synchronization changes activated. --- module/os/macos/zfs/zfs_vfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/os/macos/zfs/zfs_vfsops.c b/module/os/macos/zfs/zfs_vfsops.c index 86062c808..7727f0d0e 100644 --- a/module/os/macos/zfs/zfs_vfsops.c +++ b/module/os/macos/zfs/zfs_vfsops.c @@ -129,7 +129,7 @@ zfs_is_readonly(zfsvfs_t *zfsvfs) * syncs. (As per illumos) Unfortunately, we can not tell the difference * of when users run "sync" by hand. Sync is called on umount though. */ -uint64_t zfs_vfs_sync_paranoia = 0; +uint64_t zfs_vfs_sync_paranoia = 1; int zfs_vfs_sync(struct mount *vfsp, __unused int waitfor,