mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	A few fixes of callback typecasting (for the upcoming ClangCFI)
* zio: avoid callback typecasting * zil: avoid zil_itxg_clean() callback typecasting * zpl: decouple zpl_readpage() into two separate callbacks * nvpair: explicitly declare callbacks for xdr_array() * linux/zfs_nvops: don't use external iput() as a callback * zcp_synctask: don't use fnvlist_free() as a callback * zvol: don't use ops->zv_free() as a callback for taskq_dispatch() Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Signed-off-by: Alexander Lobakin <alobakin@pm.me> Closes #12260
This commit is contained in:
		
							parent
							
								
									0ca9558561
								
							
						
					
					
						commit
						4affa09f3e
					
				@ -589,8 +589,8 @@ extern void zio_shrink(zio_t *zio, uint64_t size);
 | 
			
		||||
 | 
			
		||||
extern int zio_wait(zio_t *zio);
 | 
			
		||||
extern void zio_nowait(zio_t *zio);
 | 
			
		||||
extern void zio_execute(zio_t *zio);
 | 
			
		||||
extern void zio_interrupt(zio_t *zio);
 | 
			
		||||
extern void zio_execute(void *zio);
 | 
			
		||||
extern void zio_interrupt(void *zio);
 | 
			
		||||
extern void zio_delay_init(zio_t *zio);
 | 
			
		||||
extern void zio_delay_interrupt(zio_t *zio);
 | 
			
		||||
extern void zio_deadman(zio_t *zio, char *tag);
 | 
			
		||||
 | 
			
		||||
@ -3213,6 +3213,56 @@ nvs_xdr_nvl_fini(nvstream_t *nvs)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * xdrproc_t-compatible callbacks for xdr_array()
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(_KERNEL) && defined(__linux__) /* Linux 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(_KERNEL) && defined(XDR_CONTROL) /* tirpc */
 | 
			
		||||
 | 
			
		||||
#define	NVS_BUILD_XDRPROC_T(type)		\
 | 
			
		||||
static bool_t					\
 | 
			
		||||
nvs_xdr_nvp_##type(XDR *xdrs, ...)		\
 | 
			
		||||
{						\
 | 
			
		||||
	va_list args;				\
 | 
			
		||||
	void *ptr;				\
 | 
			
		||||
						\
 | 
			
		||||
	va_start(args, xdrs);			\
 | 
			
		||||
	ptr = va_arg(args, void *);		\
 | 
			
		||||
	va_end(args);				\
 | 
			
		||||
						\
 | 
			
		||||
	return (xdr_##type(xdrs, ptr));		\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* FreeBSD, sunrpc */
 | 
			
		||||
 | 
			
		||||
#define	NVS_BUILD_XDRPROC_T(type)		\
 | 
			
		||||
static bool_t					\
 | 
			
		||||
nvs_xdr_nvp_##type(XDR *xdrs, void *ptr, ...)	\
 | 
			
		||||
{						\
 | 
			
		||||
	return (xdr_##type(xdrs, ptr));		\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* BEGIN CSTYLED */
 | 
			
		||||
NVS_BUILD_XDRPROC_T(char);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(short);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(u_short);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(int);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(u_int);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(longlong_t);
 | 
			
		||||
NVS_BUILD_XDRPROC_T(u_longlong_t);
 | 
			
		||||
/* END CSTYLED */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The format of xdr encoded nvpair is:
 | 
			
		||||
 * encode_size, decode_size, name string, data type, nelem, data
 | 
			
		||||
@ -3335,38 +3385,38 @@ nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
 | 
			
		||||
	case DATA_TYPE_INT8_ARRAY:
 | 
			
		||||
	case DATA_TYPE_UINT8_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t),
 | 
			
		||||
		    (xdrproc_t)xdr_char);
 | 
			
		||||
		    nvs_xdr_nvp_char);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_INT16_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t),
 | 
			
		||||
		    sizeof (int16_t), (xdrproc_t)xdr_short);
 | 
			
		||||
		    sizeof (int16_t), nvs_xdr_nvp_short);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_UINT16_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t),
 | 
			
		||||
		    sizeof (uint16_t), (xdrproc_t)xdr_u_short);
 | 
			
		||||
		    sizeof (uint16_t), nvs_xdr_nvp_u_short);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_BOOLEAN_ARRAY:
 | 
			
		||||
	case DATA_TYPE_INT32_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t),
 | 
			
		||||
		    sizeof (int32_t), (xdrproc_t)xdr_int);
 | 
			
		||||
		    sizeof (int32_t), nvs_xdr_nvp_int);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_UINT32_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t),
 | 
			
		||||
		    sizeof (uint32_t), (xdrproc_t)xdr_u_int);
 | 
			
		||||
		    sizeof (uint32_t), nvs_xdr_nvp_u_int);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_INT64_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t),
 | 
			
		||||
		    sizeof (int64_t), (xdrproc_t)xdr_longlong_t);
 | 
			
		||||
		    sizeof (int64_t), nvs_xdr_nvp_longlong_t);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_UINT64_ARRAY:
 | 
			
		||||
		ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t),
 | 
			
		||||
		    sizeof (uint64_t), (xdrproc_t)xdr_u_longlong_t);
 | 
			
		||||
		    sizeof (uint64_t), nvs_xdr_nvp_u_longlong_t);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case DATA_TYPE_STRING_ARRAY: {
 | 
			
		||||
 | 
			
		||||
@ -392,6 +392,12 @@ zfs_write_simple(znode_t *zp, const void *data, size_t len,
 | 
			
		||||
	return (error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
zfs_rele_async_task(void *arg)
 | 
			
		||||
{
 | 
			
		||||
	iput(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
zfs_zrele_async(znode_t *zp)
 | 
			
		||||
{
 | 
			
		||||
@ -411,7 +417,7 @@ zfs_zrele_async(znode_t *zp)
 | 
			
		||||
	 */
 | 
			
		||||
	if (!atomic_add_unless(&ip->i_count, -1, 1)) {
 | 
			
		||||
		VERIFY(taskq_dispatch(dsl_pool_zrele_taskq(dmu_objset_pool(os)),
 | 
			
		||||
		    (task_func_t *)iput, ip, TQ_SLEEP) != TASKQID_INVALID);
 | 
			
		||||
		    zfs_rele_async_task, ip, TQ_SLEEP) != TASKQID_INVALID);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -591,8 +591,8 @@ zpl_mmap(struct file *filp, struct vm_area_struct *vma)
 | 
			
		||||
 * only used to support mmap(2).  There will be an identical copy of the
 | 
			
		||||
 * data in the ARC which is kept up to date via .write() and .writepage().
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
zpl_readpage(struct file *filp, struct page *pp)
 | 
			
		||||
static inline int
 | 
			
		||||
zpl_readpage_common(struct page *pp)
 | 
			
		||||
{
 | 
			
		||||
	struct inode *ip;
 | 
			
		||||
	struct page *pl[1];
 | 
			
		||||
@ -620,6 +620,18 @@ zpl_readpage(struct file *filp, struct page *pp)
 | 
			
		||||
	return (error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
zpl_readpage(struct file *filp, struct page *pp)
 | 
			
		||||
{
 | 
			
		||||
	return (zpl_readpage_common(pp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
zpl_readpage_filler(void *data, struct page *pp)
 | 
			
		||||
{
 | 
			
		||||
	return (zpl_readpage_common(pp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Populate a set of pages with data for the Linux page cache.  This
 | 
			
		||||
 * function will only be called for read ahead and never for demand
 | 
			
		||||
@ -630,8 +642,7 @@ static int
 | 
			
		||||
zpl_readpages(struct file *filp, struct address_space *mapping,
 | 
			
		||||
    struct list_head *pages, unsigned nr_pages)
 | 
			
		||||
{
 | 
			
		||||
	return (read_cache_pages(mapping, pages,
 | 
			
		||||
	    (filler_t *)zpl_readpage, filp));
 | 
			
		||||
	return (read_cache_pages(mapping, pages, zpl_readpage_filler, NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
 | 
			
		||||
@ -54,6 +54,12 @@ typedef struct zcp_synctask_info {
 | 
			
		||||
	int blocks_modified;
 | 
			
		||||
} zcp_synctask_info_t;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
zcp_synctask_cleanup(void *arg)
 | 
			
		||||
{
 | 
			
		||||
	fnvlist_free(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Generic synctask interface for channel program syncfuncs.
 | 
			
		||||
 *
 | 
			
		||||
@ -275,7 +281,7 @@ zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
 | 
			
		||||
	fnvlist_add_boolean(ddsa.ddsa_snaps, dsname);
 | 
			
		||||
 | 
			
		||||
	zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
 | 
			
		||||
	    (zcp_cleanup_t *)&fnvlist_free, ddsa.ddsa_snaps);
 | 
			
		||||
	    zcp_synctask_cleanup, ddsa.ddsa_snaps);
 | 
			
		||||
 | 
			
		||||
	err = zcp_sync_task(state, dsl_dataset_snapshot_check,
 | 
			
		||||
	    dsl_dataset_snapshot_sync, &ddsa, sync, dsname);
 | 
			
		||||
@ -363,7 +369,7 @@ zcp_synctask_inherit_prop(lua_State *state, boolean_t sync,
 | 
			
		||||
	fnvlist_add_boolean(dpsa->dpsa_props, prop);
 | 
			
		||||
 | 
			
		||||
	zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
 | 
			
		||||
	    (zcp_cleanup_t *)&fnvlist_free, dpsa->dpsa_props);
 | 
			
		||||
	    zcp_synctask_cleanup, dpsa->dpsa_props);
 | 
			
		||||
 | 
			
		||||
	err = zcp_sync_task(state, zcp_synctask_inherit_prop_check,
 | 
			
		||||
	    zcp_synctask_inherit_prop_sync, &zipa, sync, dsname);
 | 
			
		||||
@ -402,7 +408,7 @@ zcp_synctask_bookmark(lua_State *state, boolean_t sync, nvlist_t *err_details)
 | 
			
		||||
	fnvlist_add_string(bmarks, new, source);
 | 
			
		||||
 | 
			
		||||
	zcp_cleanup_handler_t *zch = zcp_register_cleanup(state,
 | 
			
		||||
	    (zcp_cleanup_t *)&fnvlist_free, bmarks);
 | 
			
		||||
	    zcp_synctask_cleanup, bmarks);
 | 
			
		||||
 | 
			
		||||
	dsl_bookmark_create_arg_t dbca = {
 | 
			
		||||
		.dbca_bmarks = bmarks,
 | 
			
		||||
@ -467,8 +473,7 @@ zcp_synctask_wrapper(lua_State *state)
 | 
			
		||||
	 * Make sure err_details is properly freed, even if a fatal error is
 | 
			
		||||
	 * thrown during the synctask.
 | 
			
		||||
	 */
 | 
			
		||||
	zch = zcp_register_cleanup(state,
 | 
			
		||||
	    (zcp_cleanup_t *)&fnvlist_free, err_details);
 | 
			
		||||
	zch = zcp_register_cleanup(state, zcp_synctask_cleanup, err_details);
 | 
			
		||||
 | 
			
		||||
	zcp_synctask_info_t *info = lua_touserdata(state, lua_upvalueindex(1));
 | 
			
		||||
	boolean_t sync = lua_toboolean(state, lua_upvalueindex(2));
 | 
			
		||||
 | 
			
		||||
@ -1822,12 +1822,13 @@ zil_itx_destroy(itx_t *itx)
 | 
			
		||||
 * so no locks are needed.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
zil_itxg_clean(itxs_t *itxs)
 | 
			
		||||
zil_itxg_clean(void *arg)
 | 
			
		||||
{
 | 
			
		||||
	itx_t *itx;
 | 
			
		||||
	list_t *list;
 | 
			
		||||
	avl_tree_t *t;
 | 
			
		||||
	void *cookie;
 | 
			
		||||
	itxs_t *itxs = arg;
 | 
			
		||||
	itx_async_node_t *ian;
 | 
			
		||||
 | 
			
		||||
	list = &itxs->i_sync_list;
 | 
			
		||||
@ -2047,7 +2048,7 @@ zil_clean(zilog_t *zilog, uint64_t synced_txg)
 | 
			
		||||
	ASSERT3P(zilog->zl_dmu_pool, !=, NULL);
 | 
			
		||||
	ASSERT3P(zilog->zl_dmu_pool->dp_zil_clean_taskq, !=, NULL);
 | 
			
		||||
	taskqid_t id = taskq_dispatch(zilog->zl_dmu_pool->dp_zil_clean_taskq,
 | 
			
		||||
	    (void (*)(void *))zil_itxg_clean, clean_me, TQ_NOSLEEP);
 | 
			
		||||
	    zil_itxg_clean, clean_me, TQ_NOSLEEP);
 | 
			
		||||
	if (id == TASKQID_INVALID)
 | 
			
		||||
		zil_itxg_clean(clean_me);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1891,8 +1891,8 @@ zio_taskq_dispatch(zio_t *zio, zio_taskq_type_t q, boolean_t cutinline)
 | 
			
		||||
	 * to dispatch the zio to another taskq at the same time.
 | 
			
		||||
	 */
 | 
			
		||||
	ASSERT(taskq_empty_ent(&zio->io_tqent));
 | 
			
		||||
	spa_taskq_dispatch_ent(spa, t, q, (task_func_t *)zio_execute, zio,
 | 
			
		||||
	    flags, &zio->io_tqent);
 | 
			
		||||
	spa_taskq_dispatch_ent(spa, t, q, zio_execute, zio, flags,
 | 
			
		||||
	    &zio->io_tqent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static boolean_t
 | 
			
		||||
@ -1923,7 +1923,7 @@ zio_issue_async(zio_t *zio)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
zio_interrupt(zio_t *zio)
 | 
			
		||||
zio_interrupt(void *zio)
 | 
			
		||||
{
 | 
			
		||||
	zio_taskq_dispatch(zio, ZIO_TASKQ_INTERRUPT, B_FALSE);
 | 
			
		||||
}
 | 
			
		||||
@ -1981,8 +1981,8 @@ zio_delay_interrupt(zio_t *zio)
 | 
			
		||||
				 * OpenZFS's timeout_generic().
 | 
			
		||||
				 */
 | 
			
		||||
				tid = taskq_dispatch_delay(system_taskq,
 | 
			
		||||
				    (task_func_t *)zio_interrupt,
 | 
			
		||||
				    zio, TQ_NOSLEEP, expire_at_tick);
 | 
			
		||||
				    zio_interrupt, zio, TQ_NOSLEEP,
 | 
			
		||||
				    expire_at_tick);
 | 
			
		||||
				if (tid == TASKQID_INVALID) {
 | 
			
		||||
					/*
 | 
			
		||||
					 * Couldn't allocate a task.  Just
 | 
			
		||||
@ -2103,7 +2103,7 @@ static zio_pipe_stage_t *zio_pipeline[];
 | 
			
		||||
 * it is externally visible.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
zio_execute(zio_t *zio)
 | 
			
		||||
zio_execute(void *zio)
 | 
			
		||||
{
 | 
			
		||||
	fstrans_cookie_t cookie;
 | 
			
		||||
 | 
			
		||||
@ -2292,8 +2292,9 @@ zio_nowait(zio_t *zio)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
zio_reexecute(zio_t *pio)
 | 
			
		||||
zio_reexecute(void *arg)
 | 
			
		||||
{
 | 
			
		||||
	zio_t *pio = arg;
 | 
			
		||||
	zio_t *cio, *cio_next;
 | 
			
		||||
 | 
			
		||||
	ASSERT(pio->io_child_type == ZIO_CHILD_LOGICAL);
 | 
			
		||||
@ -4788,8 +4789,7 @@ zio_done(zio_t *zio)
 | 
			
		||||
			ASSERT(taskq_empty_ent(&zio->io_tqent));
 | 
			
		||||
			spa_taskq_dispatch_ent(zio->io_spa,
 | 
			
		||||
			    ZIO_TYPE_CLAIM, ZIO_TASKQ_ISSUE,
 | 
			
		||||
			    (task_func_t *)zio_reexecute, zio, 0,
 | 
			
		||||
			    &zio->io_tqent);
 | 
			
		||||
			    zio_reexecute, zio, 0, &zio->io_tqent);
 | 
			
		||||
		}
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1195,6 +1195,12 @@ zvol_create_minor(const char *name)
 | 
			
		||||
 * Remove minors for specified dataset including children and snapshots.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
zvol_free_task(void *arg)
 | 
			
		||||
{
 | 
			
		||||
	ops->zv_free(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
zvol_remove_minors_impl(const char *name)
 | 
			
		||||
{
 | 
			
		||||
@ -1243,8 +1249,8 @@ zvol_remove_minors_impl(const char *name)
 | 
			
		||||
			mutex_exit(&zv->zv_state_lock);
 | 
			
		||||
 | 
			
		||||
			/* Try parallel zv_free, if failed do it in place */
 | 
			
		||||
			t = taskq_dispatch(system_taskq,
 | 
			
		||||
			    (task_func_t *)ops->zv_free, zv, TQ_SLEEP);
 | 
			
		||||
			t = taskq_dispatch(system_taskq, zvol_free_task, zv,
 | 
			
		||||
			    TQ_SLEEP);
 | 
			
		||||
			if (t == TASKQID_INVALID)
 | 
			
		||||
				list_insert_head(&free_list, zv);
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user