From db7f1a91def6bbaf72dd3e9ad31255efb0bf81ab Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 5 Mar 2022 01:25:22 +0100 Subject: [PATCH] Use _Noreturn (C11; GNU89) properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Co-authored-by: Ahelenia ZiemiaƄska Signed-off-by: Alejandro Colomar Closes #13120 --- cmd/raidz_test/raidz_test.c | 2 +- cmd/zgenhostid/zgenhostid.c | 2 +- cmd/zhack/zhack.c | 4 ++-- cmd/ztest/ztest.c | 10 +++++----- config/always-compiler-options.m4 | 26 -------------------------- config/zfs-build.m4 | 1 - include/libuutil.h | 16 ++++++++-------- include/os/linux/spl/sys/thread.h | 2 +- include/sys/zfs_context.h | 4 ++-- lib/libspl/include/sys/feature_tests.h | 1 - lib/libuutil/uu_pname.c | 6 +++--- lib/libzpool/Makefile.am | 5 ----- lib/libzpool/kernel.c | 21 ++++++++++++++++++++- lib/libzpool/taskq.c | 2 +- module/lua/ldo.c | 2 +- module/zfs/arc.c | 6 +++--- module/zfs/dbuf.c | 2 +- module/zfs/dmu_recv.c | 2 +- module/zfs/dmu_redact.c | 4 ++-- module/zfs/dmu_send.c | 8 ++++---- module/zfs/mmp.c | 6 +++--- module/zfs/spa.c | 2 +- module/zfs/txg.c | 8 ++++---- module/zfs/vdev_initialize.c | 2 +- module/zfs/vdev_rebuild.c | 4 ++-- module/zfs/vdev_removal.c | 4 ++-- module/zfs/vdev_trim.c | 6 +++--- module/zfs/zthr.c | 2 +- tests/zfs-tests/cmd/mkbusy/mkbusy.c | 4 ++-- tests/zfs-tests/cmd/mkfile/mkfile.c | 2 +- 30 files changed, 76 insertions(+), 90 deletions(-) diff --git a/cmd/raidz_test/raidz_test.c b/cmd/raidz_test/raidz_test.c index a7459d8e2c..8bb38f2f72 100644 --- a/cmd/raidz_test/raidz_test.c +++ b/cmd/raidz_test/raidz_test.c @@ -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; diff --git a/cmd/zgenhostid/zgenhostid.c b/cmd/zgenhostid/zgenhostid.c index 853931c6ad..6c8f7c6127 100644 --- a/cmd/zgenhostid/zgenhostid.c +++ b/cmd/zgenhostid/zgenhostid.c @@ -36,7 +36,7 @@ #include #include -static __attribute__((noreturn)) void +static _Noreturn void usage(void) { (void) fprintf(stderr, diff --git a/cmd/zhack/zhack.c b/cmd/zhack/zhack.c index 73ce888c0b..92d20d753a 100644 --- a/cmd/zhack/zhack.c +++ b/cmd/zhack/zhack.c @@ -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; diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 73ed704714..292493584b 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -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; diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 index 9a0e83905d..8cfd27535b 100644 --- a/config/always-compiler-options.m4 +++ b/config/always-compiler-options.m4 @@ -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 # diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index 42e57cdf7a..d516f3d296 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -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 diff --git a/include/libuutil.h b/include/libuutil.h index cadc20d2d8..043152ac26 100644 --- a/include/libuutil.h +++ b/include/libuutil.h @@ -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) diff --git a/include/os/linux/spl/sys/thread.h b/include/os/linux/spl/sys/thread.h index 6248866a92..7f9f486fcd 100644 --- a/include/os/linux/spl/sys/thread.h +++ b/include/os/linux/spl/sys/thread.h @@ -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[], ...); diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 6d1fd83df5..9d99388be6 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -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 diff --git a/lib/libspl/include/sys/feature_tests.h b/lib/libspl/include/sys/feature_tests.h index be0721b505..877e0a15a8 100644 --- a/lib/libspl/include/sys/feature_tests.h +++ b/lib/libspl/include/sys/feature_tests.h @@ -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) diff --git a/lib/libuutil/uu_pname.c b/lib/libuutil/uu_pname.c index 43c9e77564..b6c9f2cc03 100644 --- a/lib/libuutil/uu_pname.c +++ b/lib/libuutil/uu_pname.c @@ -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); diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 60ffbb7ee5..e60a906a5c 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -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 = \ diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 8a588e5a9b..6b29d6d39e 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -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); diff --git a/lib/libzpool/taskq.c b/lib/libzpool/taskq.c index 8a61130911..146044bb8b 100644 --- a/lib/libzpool/taskq.c +++ b/lib/libzpool/taskq.c @@ -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; diff --git a/module/lua/ldo.c b/module/lua/ldo.c index 01e5d6fd32..2ee9f665d7 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -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 } diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 7ca37c1764..744df24235 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -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; diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 26f0d72b2f..cb2b7e5a1d 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -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; diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c index b507d37c7f..b34c1bc693 100644 --- a/module/zfs/dmu_recv.c +++ b/module/zfs/dmu_recv.c @@ -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; diff --git a/module/zfs/dmu_redact.c b/module/zfs/dmu_redact.c index 46f4982894..ab2b5f23e3 100644 --- a/module/zfs/dmu_redact.c +++ b/module/zfs/dmu_redact.c @@ -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; diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index b388a3c110..021dffefa1 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -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; diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index abdce3a32e..f8ba216959 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -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; diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 881a7c94eb..744bcb434f 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -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; diff --git a/module/zfs/txg.c b/module/zfs/txg.c index 9655efdc48..7908183cae 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -108,8 +108,8 @@ * 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; diff --git a/module/zfs/vdev_initialize.c b/module/zfs/vdev_initialize.c index ce1385d5aa..6c4528e93a 100644 --- a/module/zfs/vdev_initialize.c +++ b/module/zfs/vdev_initialize.c @@ -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; diff --git a/module/zfs/vdev_rebuild.c b/module/zfs/vdev_rebuild.c index a6866a8b26..510463b1f9 100644 --- a/module/zfs/vdev_rebuild.c +++ b/module/zfs/vdev_rebuild.c @@ -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; diff --git a/module/zfs/vdev_removal.c b/module/zfs/vdev_removal.c index 64be84edd8..6887b2f523 100644 --- a/module/zfs/vdev_removal.c +++ b/module/zfs/vdev_removal.c @@ -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; diff --git a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c index 39aee37869..77f27406ea 100644 --- a/module/zfs/vdev_trim.c +++ b/module/zfs/vdev_trim.c @@ -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; diff --git a/module/zfs/zthr.c b/module/zfs/zthr.c index 52ddffae7a..2cb600a712 100644 --- a/module/zfs/zthr.c +++ b/module/zfs/zthr.c @@ -231,7 +231,7 @@ struct zthr { const char *zthr_name; }; -static void +static _Noreturn void zthr_procedure(void *arg) { zthr_t *t = arg; diff --git a/tests/zfs-tests/cmd/mkbusy/mkbusy.c b/tests/zfs-tests/cmd/mkbusy/mkbusy.c index 50a4f90a22..c32f1ecdc3 100644 --- a/tests/zfs-tests/cmd/mkbusy/mkbusy.c +++ b/tests/zfs-tests/cmd/mkbusy/mkbusy.c @@ -31,14 +31,14 @@ #include -static __attribute__((noreturn)) void +static _Noreturn void usage(char *progname) { (void) fprintf(stderr, "Usage: %s \n", progname); exit(1); } -static __attribute__((noreturn)) void +static _Noreturn void fail(char *err) { perror(err); diff --git a/tests/zfs-tests/cmd/mkfile/mkfile.c b/tests/zfs-tests/cmd/mkfile/mkfile.c index 673cbf9e00..f59a01efac 100644 --- a/tests/zfs-tests/cmd/mkfile/mkfile.c +++ b/tests/zfs-tests/cmd/mkfile/mkfile.c @@ -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)