]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Use _Noreturn (C11; GNU89) properly
authorAlejandro Colomar <Colomar.6.4.3@GMail.com>
Sat, 5 Mar 2022 00:25:22 +0000 (01:25 +0100)
committerGitHub <noreply@github.com>
Sat, 5 Mar 2022 00:25:22 +0000 (16:25 -0800)
A function that returns with no value is a different thing from a
function that doesn't return at all.  Those are two orthogonal
concepts, commonly confused.

pthread_create(3) expects a pointer to a start routine that has a
very precise prototype:

    void *(*start_routine)(void *);

However, other thread functions, such as kernel ones, expect:

    void (*start_routine)(void *);

Providing a different one is incorrect, and has only been working
because the ABIs happen to produce a compatible function.

We should use '_Noreturn void', since it's the natural type, and
then provide a '_Noreturn void *' wrapper for pthread functions.

For consistency, replace most cases of __NORETURN or
__attribute__((noreturn)) by _Noreturn.  _Noreturn is understood
by -std=gnu89, so it should be safe to use everywhere.

Ref: https://github.com/openzfs/zfs/pull/13110#discussion_r808450136
Ref: https://software.codidact.com/posts/285972
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Co-authored-by: Ahelenia ZiemiaƄska <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Closes #13120

30 files changed:
cmd/raidz_test/raidz_test.c
cmd/zgenhostid/zgenhostid.c
cmd/zhack/zhack.c
cmd/ztest/ztest.c
config/always-compiler-options.m4
config/zfs-build.m4
include/libuutil.h
include/os/linux/spl/sys/thread.h
include/sys/zfs_context.h
lib/libspl/include/sys/feature_tests.h
lib/libuutil/uu_pname.c
lib/libzpool/Makefile.am
lib/libzpool/kernel.c
lib/libzpool/taskq.c
module/lua/ldo.c
module/zfs/arc.c
module/zfs/dbuf.c
module/zfs/dmu_recv.c
module/zfs/dmu_redact.c
module/zfs/dmu_send.c
module/zfs/mmp.c
module/zfs/spa.c
module/zfs/txg.c
module/zfs/vdev_initialize.c
module/zfs/vdev_rebuild.c
module/zfs/vdev_removal.c
module/zfs/vdev_trim.c
module/zfs/zthr.c
tests/zfs-tests/cmd/mkbusy/mkbusy.c
tests/zfs-tests/cmd/mkfile/mkfile.c

index a7459d8e2cb1d9ada48c0266cfeeb41f39b736f2..8bb38f2f72c7771c0e3b814b2553c676c4f046b1 100644 (file)
@@ -840,7 +840,7 @@ static kcondvar_t sem_cv;
 static int max_free_slots;
 static int free_slots;
 
-static void
+static _Noreturn void
 sweep_thread(void *arg)
 {
        int err = 0;
index 853931c6ad6e56cae143e945c30bc7df5ce57271..6c8f7c6127a1c2f9e33f05d04116046a23edb7d0 100644 (file)
@@ -36,7 +36,7 @@
 #include <time.h>
 #include <unistd.h>
 
-static __attribute__((noreturn)) void
+static _Noreturn void
 usage(void)
 {
        (void) fprintf(stderr,
index 73ce888c0b1d26e430592fd01cfc74e2bdeb2cde..92d20d753aedefe7336875bcf9f1fb22364075a4 100644 (file)
@@ -57,7 +57,7 @@ static importargs_t g_importargs;
 static char *g_pool;
 static boolean_t g_readonly;
 
-static __attribute__((noreturn)) void
+static _Noreturn void
 usage(void)
 {
        (void) fprintf(stderr,
@@ -87,7 +87,7 @@ usage(void)
 }
 
 
-static __attribute__((noreturn)) __attribute__((format(printf, 3, 4))) void
+static __attribute__((format(printf, 3, 4))) _Noreturn void
 fatal(spa_t *spa, void *tag, const char *fmt, ...)
 {
        va_list ap;
index 73ed704714f3f359d91e492524d5a91b8883abef..292493584bf7b7dc0690dee18d9cd3395ccd992d 100644 (file)
@@ -558,7 +558,7 @@ enum ztest_object {
        ZTEST_OBJECTS
 };
 
-static void usage(boolean_t) __NORETURN;
+static _Noreturn void usage(boolean_t);
 static int ztest_scrub_impl(spa_t *spa);
 
 /*
@@ -622,7 +622,7 @@ static void sig_handler(int signo)
 
 char *fatal_msg;
 
-static __attribute__((noreturn)) __attribute__((format(printf, 2, 3))) void
+static __attribute__((format(printf, 2, 3))) _Noreturn void
 fatal(int do_perror, char *message, ...)
 {
        va_list args;
@@ -6993,7 +6993,7 @@ ztest_resume(spa_t *spa)
        (void) zio_resume(spa);
 }
 
-static void
+static _Noreturn void
 ztest_resume_thread(void *arg)
 {
        spa_t *spa = arg;
@@ -7019,7 +7019,7 @@ ztest_resume_thread(void *arg)
        thread_exit();
 }
 
-static void
+static _Noreturn void
 ztest_deadman_thread(void *arg)
 {
        ztest_shared_t *zs = arg;
@@ -7097,7 +7097,7 @@ ztest_execute(int test, ztest_info_t *zi, uint64_t id)
                    (double)functime / NANOSEC, zi->zi_funcname);
 }
 
-static void
+static _Noreturn void
 ztest_thread(void *arg)
 {
        int rand;
index 9a0e83905de76b967e0acc7895784987d8bbd3e9..8cfd27535b578b99ab64496108bd377537f365e9 100644 (file)
@@ -181,32 +181,6 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED], [
        AC_SUBST([NO_CLOBBERED])
 ])
 
-dnl #
-dnl # Check if cc supports -Wno-cast-function-type option.
-dnl #
-dnl # We actually invoke it with the --cast-function-type option
-dnl # and infer the 'no-' version does or doesn't exist based upon
-dnl # the results.  This is required because when checking any of
-dnl # no- prefixed options gcc always returns success.
-dnl #
-AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_CAST_FUNCTION_TYPE], [
-       AC_MSG_CHECKING([whether $CC supports -Wno-cast-function-type])
-
-       saved_flags="$CFLAGS"
-       CFLAGS="$CFLAGS -Werror -Wcast-function-type"
-
-       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
-               NO_CAST_FUNCTION_TYPE=-Wno-cast-function-type
-               AC_MSG_RESULT([yes])
-       ], [
-               NO_CAST_FUNCTION_TYPE=
-               AC_MSG_RESULT([no])
-       ])
-
-       CFLAGS="$saved_flags"
-       AC_SUBST([NO_CAST_FUNCTION_TYPE])
-])
-
 dnl #
 dnl # Check if cc supports -Wimplicit-fallthrough option.
 dnl #
index 42e57cdf7a336a81411409ddbaec282b957409fb..d516f3d2969f3ddc912ddbf18413353fa9928f23 100644 (file)
@@ -210,7 +210,6 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
        AC_SUBST(CPU_COUNT)
 
        ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED
-       ZFS_AC_CONFIG_ALWAYS_CC_NO_CAST_FUNCTION_TYPE
        ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH
        ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN
        ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION
index cadc20d2d8f3d9194f4dbbccd2836dea1571850f..043152ac26b51d8d40275916819b024f377334d9 100644 (file)
@@ -85,14 +85,14 @@ extern void uu_warn(const char *, ...)
     __attribute__((format(printf, 1, 2)));
 extern void uu_vwarn(const char *, va_list)
     __attribute__((format(printf, 1, 0)));
-extern void uu_die(const char *, ...)
-    __attribute__((format(printf, 1, 2))) __NORETURN;
-extern void uu_vdie(const char *, va_list)
-    __attribute__((format(printf, 1, 0))) __NORETURN;
-extern void uu_xdie(int, const char *, ...)
-    __attribute__((format(printf, 2, 3))) __NORETURN;
-extern void uu_vxdie(int, const char *, va_list)
-    __attribute__((format(printf, 2, 0))) __NORETURN;
+extern _Noreturn void uu_die(const char *, ...)
+    __attribute__((format(printf, 1, 2)));
+extern _Noreturn void uu_vdie(const char *, va_list)
+    __attribute__((format(printf, 1, 0)));
+extern _Noreturn void uu_xdie(int, const char *, ...)
+    __attribute__((format(printf, 2, 3)));
+extern _Noreturn void uu_vxdie(int, const char *, va_list)
+    __attribute__((format(printf, 2, 0)));
 
 /*
  * Exit status functions (not to be used directly)
index 6248866a9225c6e54e7e8bb1a709d12f68fa826d..7f9f486fcd4bc1aacda6f34f8f6130c1878e21ad 100644 (file)
@@ -62,7 +62,7 @@ typedef void (*thread_func_t)(void *);
 extern kthread_t *__thread_create(caddr_t stk, size_t  stksize,
     thread_func_t func, const char *name, void *args, size_t len, proc_t *pp,
     int state, pri_t pri);
-extern void __thread_exit(void);
+extern __attribute__((noreturn)) void __thread_exit(void);
 extern struct task_struct *spl_kthread_create(int (*func)(void *),
     void *data, const char namefmt[], ...);
 
index 6d1fd83df5224b3daf36a795e514c4eb93fc6414..9d99388be6688003685df7787e8e0c1ad64f47d1 100644 (file)
@@ -153,8 +153,8 @@ extern void dprintf_setup(int *argc, char **argv);
 
 extern void cmn_err(int, const char *, ...);
 extern void vcmn_err(int, const char *, va_list);
-extern void panic(const char *, ...)  __NORETURN;
-extern void vpanic(const char *, va_list)  __NORETURN;
+extern _Noreturn void panic(const char *, ...);
+extern _Noreturn void vpanic(const char *, va_list);
 
 #define        fm_panic        panic
 
index be0721b50529f345ae0a5abaa25cb358e49570a5..877e0a15a89e0f097210c6363a8eede3f5e31fae 100644 (file)
@@ -28,7 +28,6 @@
 #define        _SYS_FEATURE_TESTS_H
 
 #define        ____cacheline_aligned
-#define        __NORETURN              __attribute__((__noreturn__))
 
 #if !defined(zfs_fallthrough) && !defined(_LIBCPP_VERSION)
 #if defined(HAVE_IMPLICIT_FALLTHROUGH)
index 43c9e77564eefe391fdafd2a2dc6007f8fafe8a4..b6c9f2cc03ef648b3bbbb51616c4a9063b8a072d 100644 (file)
@@ -40,8 +40,8 @@
 
 static const char *pname;
 
-static void
-uu_die_internal(int status, const char *format, va_list alist) __NORETURN;
+static _Noreturn void
+uu_die_internal(int status, const char *format, va_list alist);
 
 int uu_exit_ok_value = EXIT_SUCCESS;
 int uu_exit_fatal_value = EXIT_FAILURE;
@@ -110,7 +110,7 @@ uu_warn(const char *format, ...)
        va_end(alist);
 }
 
-static __attribute__((format(printf, 2, 0))) __NORETURN void
+static __attribute__((format(printf, 2, 0))) _Noreturn void
 uu_die_internal(int status, const char *format, va_list alist)
 {
        uu_warn_internal(errno, format, alist);
index 60ffbb7ee51f8dec7c1b2bdac21ec23bb56be6d7..e60a906a5cb67696c563e89956528993e53e2760 100644 (file)
@@ -24,11 +24,6 @@ AM_CFLAGS += $(ZLIB_CFLAGS)
 
 AM_CFLAGS += -DLIB_ZPOOL_BUILD
 
-# For the void (*)(void *) -> void *(*)(void *) cast in zk_thread_create()
-# See https://github.com/openzfs/zfs/pull/13110#discussion_r808450136
-kernel.$(OBJEXT): CFLAGS += $(NO_CAST_FUNCTION_TYPE)
-kernel.l$(OBJEXT): CFLAGS += $(NO_CAST_FUNCTION_TYPE)
-
 lib_LTLIBRARIES = libzpool.la
 
 USER_C = \
index 8a588e5a9b8044b92d148be73b88481cc1bbd953..6b29d6d39e6a6028336f49594d227d07e630cd13 100644 (file)
@@ -75,12 +75,28 @@ struct proc p0;
 #define        TS_STACK_MIN    MAX(PTHREAD_STACK_MIN, 32768)
 #define        TS_STACK_MAX    (256 * 1024)
 
+struct zk_thread_wrapper {
+       void (*func)(void *);
+       void *arg;
+};
+
+static void *
+zk_thread_wrapper(void *arg)
+{
+       struct zk_thread_wrapper ztw;
+       memcpy(&ztw, arg, sizeof (ztw));
+       free(arg);
+       ztw.func(ztw.arg);
+       return (NULL);
+}
+
 kthread_t *
 zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state)
 {
        pthread_attr_t attr;
        pthread_t tid;
        char *stkstr;
+       struct zk_thread_wrapper *ztw;
        int detachstate = PTHREAD_CREATE_DETACHED;
 
        VERIFY0(pthread_attr_init(&attr));
@@ -117,7 +133,10 @@ zk_thread_create(void (*func)(void *), void *arg, size_t stksize, int state)
        VERIFY0(pthread_attr_setstacksize(&attr, stksize));
        VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
 
-       VERIFY0(pthread_create(&tid, &attr, (void *(*)(void *))func, arg));
+       VERIFY(ztw = malloc(sizeof (*ztw)));
+       ztw->func = func;
+       ztw->arg = arg;
+       VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
        VERIFY0(pthread_attr_destroy(&attr));
 
        return ((void *)(uintptr_t)tid);
index 8a61130911c1c5b7cb4aecdad134ad53ffc239c2..146044bb8b0a71447242d07b8ea66caefac4b694 100644 (file)
@@ -211,7 +211,7 @@ taskq_wait_outstanding(taskq_t *tq, taskqid_t id)
        taskq_wait(tq);
 }
 
-static void
+static _Noreturn void
 taskq_thread(void *arg)
 {
        taskq_t *tq = arg;
index 01e5d6fd32d6849ddedc1bf27bd8c3ccdf064fb7..2ee9f665d77e8225853ce161ba0f178f3565a317 100644 (file)
@@ -91,7 +91,7 @@ static intptr_t stack_remaining(void) {
 typedef        struct _label_t { long long unsigned val[JMP_BUF_CNT]; } label_t;
 
 int setjmp(label_t *) __attribute__ ((__nothrow__));
-extern void longjmp(label_t *) __attribute__((__noreturn__));
+extern _Noreturn void longjmp(label_t *);
 
 #define LUAI_THROW(L,c)                longjmp(&(c)->b)
 #define LUAI_TRY(L,c,a)                if (setjmp(&(c)->b) == 0) { a }
index 7ca37c17642e226bd9cc6aeb0cee208f62b6513c..744df24235e4753d0361b20debce5080247e4b60 100644 (file)
@@ -928,7 +928,7 @@ static unsigned long l2arc_rebuild_blocks_min_l2size = 1024 * 1024 * 1024;
 
 /* L2ARC persistence rebuild control routines. */
 void l2arc_rebuild_vdev(vdev_t *vd, boolean_t reopen);
-static void l2arc_dev_rebuild_thread(void *arg);
+static _Noreturn void l2arc_dev_rebuild_thread(void *arg);
 static int l2arc_rebuild(l2arc_dev_t *dev);
 
 /* L2ARC persistence read I/O routines. */
@@ -9706,7 +9706,7 @@ l2arc_hdr_limit_reached(void)
  * This thread feeds the L2ARC at regular intervals.  This is the beating
  * heart of the L2ARC.
  */
-static void
+static _Noreturn void
 l2arc_feed_thread(void *unused)
 {
        (void) unused;
@@ -10145,7 +10145,7 @@ l2arc_spa_rebuild_start(spa_t *spa)
 /*
  * Main entry point for L2ARC rebuilding.
  */
-static void
+static _Noreturn void
 l2arc_dev_rebuild_thread(void *arg)
 {
        l2arc_dev_t *dev = arg;
index 26f0d72b2fecbcd5f0799a8907fa6c874df9a927..cb2b7e5a1def9cc6e61acc16d7534bd27ab1f00c 100644 (file)
@@ -778,7 +778,7 @@ dbuf_evict_one(void)
  * of the dbuf cache is at or below the maximum size. Once the dbuf is aged
  * out of the cache it is destroyed and becomes eligible for arc eviction.
  */
-static void
+static _Noreturn void
 dbuf_evict_thread(void *unused)
 {
        (void) unused;
index b507d37c7f78018099a004511566b104f9fbd5a2..b34c1bc6934e99ed1cd33d73814fd53f558643db 100644 (file)
@@ -2802,7 +2802,7 @@ receive_process_record(struct receive_writer_arg *rwa,
  * dmu_recv_stream's worker thread; pull records off the queue, and then call
  * receive_process_record  When we're done, signal the main thread and exit.
  */
-static void
+static _Noreturn void
 receive_writer_thread(void *arg)
 {
        struct receive_writer_arg *rwa = arg;
index 46f4982894b543c72bc0ab2407f9ab8669857aae..ab2b5f23e3f78b32fb51cc63e08102196c302d16 100644 (file)
@@ -351,7 +351,7 @@ redact_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
        return (0);
 }
 
-static void
+static _Noreturn void
 redact_traverse_thread(void *arg)
 {
        struct redact_thread_arg *rt_arg = arg;
@@ -837,7 +837,7 @@ struct redact_merge_thread_arg {
        int error_code;
 };
 
-static void
+static _Noreturn void
 redact_merge_thread(void *arg)
 {
        struct redact_merge_thread_arg *rmta = arg;
index b388a3c1101b3414c33b455aebb1fea80064544d..021dffefa14140478095e776f405d7b2341358a3 100644 (file)
@@ -1234,7 +1234,7 @@ redact_list_cb(redact_block_phys_t *rb, void *arg)
  * error code of the thread in case something goes wrong, and pushes the End of
  * Stream record when the traverse_dataset call has finished.
  */
-static void
+static _Noreturn void
 send_traverse_thread(void *arg)
 {
        struct send_thread_arg *st_arg = arg;
@@ -1324,7 +1324,7 @@ get_next_range(bqueue_t *bq, struct send_range *prev)
        return (next);
 }
 
-static void
+static _Noreturn void
 redact_list_thread(void *arg)
 {
        struct redact_list_thread_arg *rlt_arg = arg;
@@ -1519,7 +1519,7 @@ find_next_range(struct send_range **ranges, bqueue_t **qs, uint64_t *out_mask)
  * data from the redact_list_thread and use that to determine which blocks
  * should be redacted.
  */
-static void
+static _Noreturn void
 send_merge_thread(void *arg)
 {
        struct send_merge_thread_arg *smt_arg = arg;
@@ -1744,7 +1744,7 @@ enqueue_range(struct send_reader_thread_arg *srta, bqueue_t *q, dnode_t *dn,
  * some indirect blocks can be discarded because they're not holes. Second,
  * it issues prefetches for the data we need to send.
  */
-static void
+static _Noreturn void
 send_reader_thread(void *arg)
 {
        struct send_reader_thread_arg *srta = arg;
index abdce3a32e6a8ac6ebf8cfa4d8c9ad30c716767b..f8ba2169591b53bd28589592eb7099064ac8082a 100644 (file)
@@ -187,7 +187,7 @@ uint_t zfs_multihost_import_intervals = MMP_DEFAULT_IMPORT_INTERVALS;
 uint_t zfs_multihost_fail_intervals = MMP_DEFAULT_FAIL_INTERVALS;
 
 static void *const mmp_tag = "mmp_write_uberblock";
-static void mmp_thread(void *arg);
+static _Noreturn void mmp_thread(void *arg);
 
 void
 mmp_init(spa_t *spa)
@@ -217,7 +217,7 @@ mmp_thread_enter(mmp_thread_t *mmp, callb_cpr_t *cpr)
        mutex_enter(&mmp->mmp_thread_lock);
 }
 
-static void
+static _Noreturn void
 mmp_thread_exit(mmp_thread_t *mmp, kthread_t **mpp, callb_cpr_t *cpr)
 {
        ASSERT(*mpp != NULL);
@@ -537,7 +537,7 @@ mmp_write_uberblock(spa_t *spa)
        zio_nowait(zio);
 }
 
-static void
+static _Noreturn void
 mmp_thread(void *arg)
 {
        spa_t *spa = (spa_t *)arg;
index 881a7c94eb41a1a6b4709cc40a6bc28cccc2633d..744bcb434f06a0cb6aa619bd9eb4c73ae9a0e12c 100644 (file)
@@ -8139,7 +8139,7 @@ spa_async_autoexpand(spa_t *spa, vdev_t *vd)
        spa_event_notify(vd->vdev_spa, vd, NULL, ESC_ZFS_VDEV_AUTOEXPAND);
 }
 
-static void
+static _Noreturn void
 spa_async_thread(void *arg)
 {
        spa_t *spa = (spa_t *)arg;
index 9655efdc4813546915968501075451bf378245e0..7908183caee7493c77527170cbd9e3567fef8b83 100644 (file)
  * now transition to the syncing state.
  */
 
-static void txg_sync_thread(void *arg);
-static void txg_quiesce_thread(void *arg);
+static _Noreturn void txg_sync_thread(void *arg);
+static _Noreturn void txg_quiesce_thread(void *arg);
 
 int zfs_txg_timeout = 5;       /* max seconds worth of delta per txg */
 
@@ -514,7 +514,7 @@ txg_has_quiesced_to_sync(dsl_pool_t *dp)
        return (tx->tx_quiesced_txg != 0);
 }
 
-static void
+static _Noreturn void
 txg_sync_thread(void *arg)
 {
        dsl_pool_t *dp = arg;
@@ -605,7 +605,7 @@ txg_sync_thread(void *arg)
        }
 }
 
-static void
+static _Noreturn void
 txg_quiesce_thread(void *arg)
 {
        dsl_pool_t *dp = arg;
index ce1385d5aab1347a32d22765ffb4d2ce9bd31743..6c4528e93ad65de086e02aabcd4397e95baa09ad 100644 (file)
@@ -488,7 +488,7 @@ vdev_initialize_range_add(void *arg, uint64_t start, uint64_t size)
        vdev_xlate_walk(vd, &logical_rs, vdev_initialize_xlate_range_add, arg);
 }
 
-static void
+static _Noreturn void
 vdev_initialize_thread(void *arg)
 {
        vdev_t *vd = arg;
index a6866a8b263cd5703bb5dcdec1cc366b9feb2d4a..510463b1f97088b33647e73426db2598cad241d4 100644 (file)
@@ -133,7 +133,7 @@ static int zfs_rebuild_scrub_enabled = 1;
 /*
  * For vdev_rebuild_initiate_sync() and vdev_rebuild_reset_sync().
  */
-static void vdev_rebuild_thread(void *arg);
+static _Noreturn void vdev_rebuild_thread(void *arg);
 
 /*
  * Clear the per-vdev rebuild bytes value for a vdev tree.
@@ -736,7 +736,7 @@ vdev_rebuild_load(vdev_t *vd)
  * Each scan thread is responsible for rebuilding a top-level vdev.  The
  * rebuild progress in tracked on-disk in VDEV_TOP_ZAP_VDEV_REBUILD_PHYS.
  */
-static void
+static _Noreturn void
 vdev_rebuild_thread(void *arg)
 {
        vdev_t *vd = arg;
index 64be84edd8f5d5218856abe3cfa3debb15363536..6887b2f523772ff521f0db5a76b77eb4cde15b9e 100644 (file)
@@ -140,7 +140,7 @@ int zfs_removal_suspend_progress = 0;
 
 #define        VDEV_REMOVAL_ZAP_OBJS   "lzap"
 
-static void spa_vdev_remove_thread(void *arg);
+static _Noreturn void spa_vdev_remove_thread(void *arg);
 static int spa_vdev_remove_cancel_impl(spa_t *spa);
 
 static void
@@ -1589,7 +1589,7 @@ spa_remove_max_segment(spa_t *spa)
  * TXG have completed (see spa_txg_zio) and writes the new mappings to disk
  * (see vdev_mapping_sync()).
  */
-static void
+static _Noreturn void
 spa_vdev_remove_thread(void *arg)
 {
        spa_t *spa = arg;
index 39aee3786984ac32ad95dd5d6b442dba05694966..77f27406ea0134e7def92b0f97b830931b1bf2b8 100644 (file)
@@ -834,7 +834,7 @@ vdev_trim_range_add(void *arg, uint64_t start, uint64_t size)
  * by its ms_allocatable.  While a metaslab is undergoing trimming it is
  * not eligible for new allocations.
  */
-static void
+static _Noreturn void
 vdev_trim_thread(void *arg)
 {
        vdev_t *vd = arg;
@@ -1175,7 +1175,7 @@ vdev_trim_range_verify(void *arg, uint64_t start, uint64_t size)
  * N.B. This behavior is different from a manual TRIM where a thread
  * is created for each leaf vdev, instead of each top-level vdev.
  */
-static void
+static _Noreturn void
 vdev_autotrim_thread(void *arg)
 {
        vdev_t *vd = arg;
@@ -1514,7 +1514,7 @@ vdev_autotrim_restart(spa_t *spa)
                vdev_autotrim(spa);
 }
 
-static void
+static _Noreturn void
 vdev_trim_l2arc_thread(void *arg)
 {
        vdev_t          *vd = arg;
index 52ddffae7aaa7dbbbb0e85f3beef8336cf2c6608..2cb600a7124e3346de4415ab24ba4a9c7987ac76 100644 (file)
@@ -231,7 +231,7 @@ struct zthr {
        const char      *zthr_name;
 };
 
-static void
+static _Noreturn void
 zthr_procedure(void *arg)
 {
        zthr_t *t = arg;
index 50a4f90a226a6bdb15c44ef95f3938690f2ad333..c32f1ecdc3b9425f7865185584e9f04fa4054aa4 100644 (file)
 #include <string.h>
 
 
-static __attribute__((noreturn)) void
+static _Noreturn void
 usage(char *progname)
 {
        (void) fprintf(stderr, "Usage: %s <dirname|filename>\n", progname);
        exit(1);
 }
 
-static __attribute__((noreturn)) void
+static _Noreturn void
 fail(char *err)
 {
        perror(err);
index 673cbf9e0069dff474016688f3f15a1957fc1795..f59a01efaca2e5d28404703fd7a2b84585505d4f 100644 (file)
@@ -44,7 +44,7 @@
 
 #define        FILE_MODE       (S_ISVTX + S_IRUSR + S_IWUSR)
 
-static void usage(void) __attribute__((noreturn));
+static _Noreturn void usage(void);
 
 int
 main(int argc, char **argv)